From 45d76c1afe4b5e21cea947113b14682c8a6d4c1b Mon Sep 17 00:00:00 2001 From: Ciaran Morinan Date: Fri, 19 Jun 2026 15:59:41 +0100 Subject: [PATCH 01/21] introduce supply chain view shell --- apps/hash-api/src/index.ts | 3 + apps/hash-api/src/query.ts | 80 + .../src/query/queries/supply-chain.ts | 128 + .../src/query/queries/supply-chain/dataset.ts | 90 + apps/hash-api/src/query/resolve-query.test.ts | 152 + apps/hash-api/src/query/resolve-query.ts | 171 + apps/hash-api/src/query/shared/errors.ts | 34 + .../src/query/shared/query-registry.ts | 81 + .../src/query/shared/storage-key.test.ts | 76 + apps/hash-api/src/query/shared/storage-key.ts | 39 + apps/hash-api/src/seed-data/index.ts | 8 + .../src/seed-data/seed-supply-chain-demo.ts | 141 + apps/hash-api/src/seed-data/seed-users.ts | 2 + .../2026-06-17.1/_global/supplier-lines.json | 3046 ++ .../_global/supplier_performance.json | 716 + .../2026-06-17.1/harbor-dark-roast/graph.json | 16588 +++++++++ .../steps/dest_dwell_hub1.json | 431 + .../steps/intermed_dwell_green_blend.json | 593 + .../steps/post_qa_ship_pla.json | 512 + .../steps/procurement_highland_arabica.json | 3303 ++ .../steps/procurement_lowland_robusta.json | 2573 ++ .../steps/procurement_washed_bourbon.json | 2249 ++ .../steps/prod_duration_green_blend.json | 922 + .../prod_duration_harbor_dark_roast.json | 1147 + .../steps/prod_to_qa_pla.json | 580 + .../steps/raw_dwell_highland_arabica.json | 687 + .../steps/raw_dwell_lowland_robusta.json | 561 + .../steps/raw_dwell_washed_bourbon.json | 565 + .../steps/transit_pla_hub1.json | 436 + .../2026-06-17.1/manifest.json | 72 + .../2026-06-17.1/meadow-espresso/graph.json | 16588 +++++++++ .../steps/dest_dwell_hub1.json | 432 + .../steps/intermed_dwell_green_blend.json | 595 + .../steps/post_qa_ship_pla.json | 514 + .../steps/procurement_highland_arabica.json | 3304 ++ .../steps/procurement_lowland_robusta.json | 2575 ++ .../steps/procurement_washed_bourbon.json | 2251 ++ .../steps/prod_duration_green_blend.json | 924 + .../prod_duration_harbor_dark_roast.json | 1148 + .../meadow-espresso/steps/prod_to_qa_pla.json | 581 + .../steps/raw_dwell_highland_arabica.json | 689 + .../steps/raw_dwell_lowland_robusta.json | 563 + .../steps/raw_dwell_washed_bourbon.json | 567 + .../steps/transit_pla_hub1.json | 437 + .../2026-06-17.1/products.json | 22 + .../2026-06-17.1/riverside-decaf/graph.json | 16588 +++++++++ .../steps/dest_dwell_hub1.json | 432 + .../steps/intermed_dwell_green_blend.json | 595 + .../steps/post_qa_ship_pla.json | 514 + .../steps/procurement_highland_arabica.json | 3304 ++ .../steps/procurement_lowland_robusta.json | 2575 ++ .../steps/procurement_washed_bourbon.json | 2251 ++ .../steps/prod_duration_green_blend.json | 924 + .../prod_duration_harbor_dark_roast.json | 1148 + .../riverside-decaf/steps/prod_to_qa_pla.json | 581 + .../steps/raw_dwell_highland_arabica.json | 689 + .../steps/raw_dwell_lowland_robusta.json | 563 + .../steps/raw_dwell_washed_bourbon.json | 567 + .../steps/transit_pla_hub1.json | 437 + .../site/harbor-roastery/summary.json | 29435 ++++++++++++++++ .../supply-chain-demo/2026-06-17.1/sites.json | 6 + .../summit-medium-roast/graph.json | 16588 +++++++++ .../steps/dest_dwell_hub1.json | 432 + .../steps/intermed_dwell_green_blend.json | 595 + .../steps/post_qa_ship_pla.json | 514 + .../steps/procurement_highland_arabica.json | 3304 ++ .../steps/procurement_lowland_robusta.json | 2575 ++ .../steps/procurement_washed_bourbon.json | 2251 ++ .../steps/prod_duration_green_blend.json | 924 + .../prod_duration_harbor_dark_roast.json | 1148 + .../steps/prod_to_qa_pla.json | 581 + .../steps/raw_dwell_highland_arabica.json | 689 + .../steps/raw_dwell_lowland_robusta.json | 563 + .../steps/raw_dwell_washed_bourbon.json | 567 + .../steps/transit_pla_hub1.json | 437 + .../seed-data/supply-chain-demo/current.json | 3 + .../src/storage/local-file-storage.ts | 8 + apps/hash-frontend/package.json | 4 + apps/hash-frontend/panda.config.ts | 11 +- .../src/lib/supply-chain/data.ts | 119 + .../src/lib/supply-chain/query-client.ts | 104 + apps/hash-frontend/src/pages/_app.page.tsx | 7 + .../src/pages/supply-chain/index.page.tsx | 27 + .../product/[product-id].page.tsx | 91 + .../shared/supply-chain-layout.tsx | 62 + .../supply-chain/site/[site-id].page.tsx | 22 + .../[product-id]/[step-id].page.tsx | 36 + .../layout/layout-with-sidebar/sidebar.tsx | 14 +- infra/compose/compose.yml | 2 +- .../hash-backend-utils/src/file-storage.ts | 20 + .../file-storage/aws-s3-storage-provider.ts | 22 + .../src/feature-flags.ts | 4 + .../hash-isomorphic-utils/src/query/types.ts | 64 + .../legacy-base-tsconfig-to-refactor.json | 3 + .../graph/knowledge/system-types/file.test.ts | 1 + .../src/tests/util.ts | 5 + yarn.lock | 284 +- 97 files changed, 159848 insertions(+), 18 deletions(-) create mode 100644 apps/hash-api/src/query.ts create mode 100644 apps/hash-api/src/query/queries/supply-chain.ts create mode 100644 apps/hash-api/src/query/queries/supply-chain/dataset.ts create mode 100644 apps/hash-api/src/query/resolve-query.test.ts create mode 100644 apps/hash-api/src/query/resolve-query.ts create mode 100644 apps/hash-api/src/query/shared/errors.ts create mode 100644 apps/hash-api/src/query/shared/query-registry.ts create mode 100644 apps/hash-api/src/query/shared/storage-key.test.ts create mode 100644 apps/hash-api/src/query/shared/storage-key.ts create mode 100644 apps/hash-api/src/seed-data/seed-supply-chain-demo.ts create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier-lines.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier_performance.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/graph.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/dest_dwell_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/intermed_dwell_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/post_qa_ship_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_harbor_dark_roast.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_to_qa_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/transit_pla_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/manifest.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/graph.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/dest_dwell_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/intermed_dwell_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/post_qa_ship_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_harbor_dark_roast.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_to_qa_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/transit_pla_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/products.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/graph.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/dest_dwell_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/intermed_dwell_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/post_qa_ship_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_harbor_dark_roast.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_to_qa_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/transit_pla_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/site/harbor-roastery/summary.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/sites.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/graph.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/dest_dwell_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/intermed_dwell_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/post_qa_ship_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_green_blend.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_harbor_dark_roast.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_to_qa_pla.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_highland_arabica.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_lowland_robusta.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_washed_bourbon.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/transit_pla_hub1.json create mode 100644 apps/hash-api/src/seed-data/supply-chain-demo/current.json create mode 100644 apps/hash-frontend/src/lib/supply-chain/data.ts create mode 100644 apps/hash-frontend/src/lib/supply-chain/query-client.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/index.page.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx create mode 100644 libs/@local/hash-isomorphic-utils/src/query/types.ts diff --git a/apps/hash-api/src/index.ts b/apps/hash-api/src/index.ts index f5635297949..ae0a0fdcd92 100644 --- a/apps/hash-api/src/index.ts +++ b/apps/hash-api/src/index.ts @@ -86,6 +86,7 @@ import { port, } from "./lib/env-config"; import { logger } from "./logger"; +import { setupQueryHandler } from "./query"; import { seedOrgsAndUsers } from "./seed-data"; import { setupFileDownloadProxyHandler, @@ -747,6 +748,8 @@ const main = async () => { setupFileDownloadProxyHandler(app, keyv); + setupQueryHandler(app, keyv); + setupBlockProtocolExternalServiceMethodProxy(app); app.get("/", (_req, res) => { diff --git a/apps/hash-api/src/query.ts b/apps/hash-api/src/query.ts new file mode 100644 index 00000000000..4e0cbb314fb --- /dev/null +++ b/apps/hash-api/src/query.ts @@ -0,0 +1,80 @@ +import { supplyChainQueries } from "./query/queries/supply-chain"; +import { resolveInvocation } from "./query/resolve-query"; +import { registerQueries } from "./query/shared/query-registry"; + +import type { + QueryRequest, + QueryResponse, +} from "@local/hash-isomorphic-utils/query/types"; +import type { Express } from "express"; +import type Keyv from "keyv"; + +/** Upper bound on invocations per batch request, to bound work per call. */ +const MAX_BATCH_SIZE = 25; + +let queriesRegistered = false; + +/** + * Register the built-in named queries. Idempotent so repeated setup calls (e.g. + * across test harness reinitialisation) don't throw on duplicate registration. + */ +const ensureQueriesRegistered = () => { + if (queriesRegistered) { + return; + } + registerQueries(supplyChainQueries); + queriesRegistered = true; +}; + +/** + * Mounts the generic query gateway at `POST /api/query`. + * + * The gateway is a thin control plane: it authenticates the caller, authorises + * each invocation against its scoped web(s), resolves named queries to stored + * artifacts, and returns short-lived URLs the client fetches directly from + * storage (the data plane). Artifact bytes never pass through the API. + */ +export const setupQueryHandler = (app: Express, cache: Keyv) => { + ensureQueriesRegistered(); + + app.post("/api/query", async (req, res) => { + const { user } = req; + if (!user) { + res.status(401).json({ error: "Authentication required" }); + return; + } + + const body = req.body as QueryRequest | undefined; + if (!body || !Array.isArray(body.requests)) { + res + .status(400) + .json({ + error: "Request body must be { requests: QueryInvocation[] }", + }); + return; + } + + if (body.requests.length > MAX_BATCH_SIZE) { + res + .status(400) + .json({ error: `Too many requests (max ${MAX_BATCH_SIZE})` }); + return; + } + + const { graphApi, uploadProvider } = req.context; + + const results = await Promise.all( + body.requests.map((invocation) => + resolveInvocation({ + invocation, + actorId: user.accountId, + graphApi, + uploadProvider, + cache, + }), + ), + ); + + res.json({ results } satisfies QueryResponse); + }); +}; diff --git a/apps/hash-api/src/query/queries/supply-chain.ts b/apps/hash-api/src/query/queries/supply-chain.ts new file mode 100644 index 00000000000..126d1615e93 --- /dev/null +++ b/apps/hash-api/src/query/queries/supply-chain.ts @@ -0,0 +1,128 @@ +import { QueryNotFoundError } from "../shared/errors"; +import { requireSlugArg } from "../shared/storage-key"; +import { resolveDataset } from "./supply-chain/dataset"; + +import type { NamedQuery } from "../shared/query-registry"; + +/** + * Named queries backing the value-chain-timing views. Every query is scoped to + * a single web (the dataset owner) and resolves to one or more JSON artifacts. + * + * Storage layout (under `supply-chain/{webId}/{version}/`): + * products.json + * sites.json + * {productId}/graph.json + * {productId}/steps/{stepId}.json + * _global/supplier_performance.json + * _global/supplier-lines.json + * site/{siteId}/summary.json + */ + +const listProducts: NamedQuery = { + name: "listProducts", + resolve: async (ctx) => { + const { base } = await resolveDataset(ctx); + return { + status: "ready", + artifacts: [{ name: "products", key: `${base}/products.json` }], + }; + }, +}; + +const listSites: NamedQuery = { + name: "listSites", + resolve: async (ctx) => { + const { base } = await resolveDataset(ctx); + return { + status: "ready", + artifacts: [{ name: "sites", key: `${base}/sites.json` }], + }; + }, +}; + +const productGraph: NamedQuery = { + name: "productGraph", + resolve: async (ctx) => { + const productId = requireSlugArg(ctx.args, "productId"); + const { base, manifest } = await resolveDataset(ctx); + + if (!manifest.products.includes(productId)) { + throw new QueryNotFoundError(`Unknown product "${productId}"`); + } + + return { + status: "ready", + artifacts: [{ name: "graph", key: `${base}/${productId}/graph.json` }], + }; + }, +}; + +const stepDetail: NamedQuery = { + name: "stepDetail", + resolve: async (ctx) => { + const productId = requireSlugArg(ctx.args, "productId"); + const stepId = requireSlugArg(ctx.args, "stepId"); + const { base, manifest } = await resolveDataset(ctx); + + if (!manifest.products.includes(productId)) { + throw new QueryNotFoundError(`Unknown product "${productId}"`); + } + if (!(manifest.steps[productId] ?? []).includes(stepId)) { + throw new QueryNotFoundError( + `Unknown step "${stepId}" for product "${productId}"`, + ); + } + + return { + status: "ready", + artifacts: [ + { name: "step", key: `${base}/${productId}/steps/${stepId}.json` }, + ], + }; + }, +}; + +const supplierPerformance: NamedQuery = { + name: "supplierPerformance", + resolve: async (ctx) => { + const { base } = await resolveDataset(ctx); + return { + status: "ready", + artifacts: [ + { + name: "performance", + key: `${base}/_global/supplier_performance.json`, + }, + { name: "lines", key: `${base}/_global/supplier-lines.json` }, + ], + }; + }, +}; + +const siteSummary: NamedQuery = { + name: "siteSummary", + resolve: async (ctx) => { + const siteId = requireSlugArg(ctx.args, "siteId"); + const { base, manifest } = await resolveDataset(ctx); + + if (!manifest.sites.includes(siteId)) { + throw new QueryNotFoundError(`Unknown site "${siteId}"`); + } + + return { + status: "ready", + artifacts: [ + { name: "summary", key: `${base}/site/${siteId}/summary.json` }, + ], + }; + }, +}; + +export const supplyChainQueries: readonly NamedQuery[] = [ + listProducts, + listSites, + productGraph, + stepDetail, + supplierPerformance, + siteSummary, +]; diff --git a/apps/hash-api/src/query/queries/supply-chain/dataset.ts b/apps/hash-api/src/query/queries/supply-chain/dataset.ts new file mode 100644 index 00000000000..9488ea3a9f7 --- /dev/null +++ b/apps/hash-api/src/query/queries/supply-chain/dataset.ts @@ -0,0 +1,90 @@ +import { DatasetUnavailableError } from "../../shared/errors"; + +import type { QueryResolutionContext } from "../../shared/query-registry"; +import type { WebId } from "@blockprotocol/type-system"; + +/** Top-level storage namespace for all supply-chain analysis artifacts. */ +export const SUPPLY_CHAIN_NAMESPACE = "supply-chain"; + +/** + * Dataset pointer written by the seed/publish step. Indirecting through a + * pointer (rather than a hard-coded version) lets a new dataset be published + * atomically by flipping `current.json` once all `{version}/…` objects exist. + */ +export interface DatasetPointer { + datasetVersion: string; +} + +/** + * Manifest enumerating every valid id in a published dataset. Used both to + * validate client-supplied ids (so only known artifacts are resolvable) and to + * answer list-style queries' membership checks. + */ +export interface SupplyChainManifest { + datasetVersion: string; + products: string[]; + sites: string[]; + /** Map of productId -> the step ids available for that product. */ + steps: Record; +} + +export const datasetPointerKey = (webId: WebId): string => + `${SUPPLY_CHAIN_NAMESPACE}/${webId}/current.json`; + +export const datasetBaseKey = (webId: WebId, version: string): string => + `${SUPPLY_CHAIN_NAMESPACE}/${webId}/${version}`; + +export const manifestKey = (webId: WebId, version: string): string => + `${datasetBaseKey(webId, version)}/manifest.json`; + +const parseJson = (buffer: Buffer, what: string): T => { + try { + return JSON.parse(buffer.toString("utf8")) as T; + } catch { + throw new DatasetUnavailableError(`Malformed ${what}`); + } +}; + +/** + * Resolve the current dataset version and manifest for a web. Throws + * {@link DatasetUnavailableError} if the web has no published dataset. + */ +export const resolveDataset = async ( + ctx: QueryResolutionContext, +): Promise<{ + version: string; + base: string; + manifest: SupplyChainManifest; +}> => { + const pointerBytes = await ctx.loadArtifact(datasetPointerKey(ctx.webId)); + if (!pointerBytes) { + throw new DatasetUnavailableError( + `No supply-chain dataset published for web ${ctx.webId}`, + ); + } + + const { datasetVersion } = parseJson( + pointerBytes, + "dataset pointer", + ); + if (!datasetVersion) { + throw new DatasetUnavailableError("Dataset pointer missing datasetVersion"); + } + + const manifestBytes = await ctx.loadArtifact( + manifestKey(ctx.webId, datasetVersion), + ); + if (!manifestBytes) { + throw new DatasetUnavailableError( + `Dataset manifest missing for web ${ctx.webId} version ${datasetVersion}`, + ); + } + + const manifest = parseJson(manifestBytes, "manifest"); + + return { + version: datasetVersion, + base: datasetBaseKey(ctx.webId, datasetVersion), + manifest, + }; +}; diff --git a/apps/hash-api/src/query/resolve-query.test.ts b/apps/hash-api/src/query/resolve-query.test.ts new file mode 100644 index 00000000000..d1c506e96bb --- /dev/null +++ b/apps/hash-api/src/query/resolve-query.test.ts @@ -0,0 +1,152 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import type { + ActorEntityUuid, + RoleName, + WebId, +} from "@blockprotocol/type-system"; +import type { FileStorageProvider } from "@local/hash-backend-utils/file-storage"; +import type Keyv from "keyv"; + +vi.mock("@local/hash-graph-sdk/principal/actor-group", () => ({ + getActorGroupRole: vi.fn(), +})); + +vi.mock("../logger", () => ({ + logger: { warn: vi.fn(), error: vi.fn(), info: vi.fn() }, +})); + +import { getActorGroupRole } from "@local/hash-graph-sdk/principal/actor-group"; + +import { supplyChainQueries } from "./queries/supply-chain"; +import { resolveInvocation } from "./resolve-query"; +import { clearQueryRegistry, registerQueries } from "./shared/query-registry"; + +import type { GraphApi } from "../graph/context-types"; + +const mockedGetRole = vi.mocked(getActorGroupRole); + +const WEB_ID = "web-test" as WebId; +const ACTOR_ID = "actor-test" as ActorEntityUuid; +const VERSION = "2026-06-15"; + +const manifest = { + datasetVersion: VERSION, + products: ["democat-x100-extr"], + sites: ["demo-plant"], + steps: { "democat-x100-extr": ["prod_to_qa_pla"] }, +}; + +const storedFiles: Record = { + [`supply-chain/${WEB_ID}/current.json`]: JSON.stringify({ + datasetVersion: VERSION, + }), + [`supply-chain/${WEB_ID}/${VERSION}/manifest.json`]: JSON.stringify(manifest), +}; + +const uploadProvider = { + downloadDirect: async ({ key }: { key: string }) => { + const value = storedFiles[key]; + if (value === undefined) { + throw new Error(`missing: ${key}`); + } + return Buffer.from(value); + }, + presignDownloadByKey: async ({ key }: { key: string }) => + `https://signed.example/${key}`, +} as unknown as FileStorageProvider; + +const cache = { + get: async () => undefined, + set: async () => true, +} as unknown as Keyv; + +const resolve = ( + query: string, + args: Record = {}, + webIds: WebId[] = [WEB_ID], +) => + resolveInvocation({ + invocation: { id: "test", query, args, webIds }, + actorId: ACTOR_ID, + graphApi: {} as GraphApi, + uploadProvider, + cache, + }); + +describe("resolveInvocation (supply-chain queries)", () => { + beforeEach(() => { + clearQueryRegistry(); + registerQueries(supplyChainQueries); + mockedGetRole.mockReset(); + mockedGetRole.mockResolvedValue("member" as RoleName); + }); + + it("resolves productGraph to a presigned graph artifact", async () => { + const result = await resolve("productGraph", { + productId: "democat-x100-extr", + }); + + expect(result.status).toBe("ready"); + expect(result.artifacts).toHaveLength(1); + expect(result.artifacts![0]!.name).toBe("graph"); + expect(result.artifacts![0]!.url).toContain( + `${VERSION}/democat-x100-extr/graph.json`, + ); + }); + + it("resolves stepDetail when the step is in the manifest", async () => { + const result = await resolve("stepDetail", { + productId: "democat-x100-extr", + stepId: "prod_to_qa_pla", + }); + expect(result.status).toBe("ready"); + expect(result.artifacts![0]!.url).toContain( + "democat-x100-extr/steps/prod_to_qa_pla.json", + ); + }); + + it("errors for an unknown product", async () => { + const result = await resolve("productGraph", { + productId: "does-not-exist", + }); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/unknown product/i); + }); + + it("errors for an unknown step", async () => { + const result = await resolve("stepDetail", { + productId: "democat-x100-extr", + stepId: "nope", + }); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/unknown step/i); + }); + + it("rejects path-traversal product ids before touching storage", async () => { + const result = await resolve("productGraph", { productId: "../secrets" }); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/slug/i); + }); + + it("denies access when the actor has no role in the web", async () => { + mockedGetRole.mockResolvedValue(null); + const result = await resolve("productGraph", { + productId: "democat-x100-extr", + }); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/access/i); + }); + + it("errors for an unknown query name", async () => { + const result = await resolve("noSuchQuery"); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/unknown query/i); + }); + + it("errors when no webId is supplied", async () => { + const result = await resolve("listProducts", {}, []); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/webId/i); + }); +}); diff --git a/apps/hash-api/src/query/resolve-query.ts b/apps/hash-api/src/query/resolve-query.ts new file mode 100644 index 00000000000..b28a7c6529b --- /dev/null +++ b/apps/hash-api/src/query/resolve-query.ts @@ -0,0 +1,171 @@ +import { getActorGroupRole } from "@local/hash-graph-sdk/principal/actor-group"; + +import { logger } from "../logger"; +import { + DatasetUnavailableError, + QueryArgError, + QueryNotFoundError, +} from "./shared/errors"; +import { getQuery } from "./shared/query-registry"; + +import type { GraphApi } from "../graph/context-types"; +import type { ActorEntityUuid } from "@blockprotocol/type-system"; +import type { FileStorageProvider } from "@local/hash-backend-utils/file-storage"; +import type { + QueryInvocation, + QueryResult, +} from "@local/hash-isomorphic-utils/query/types"; +import type Keyv from "keyv"; + +/** + * Presigned URLs are short-lived: the frontend re-queries the gateway when a + * URL nears expiry rather than holding long-lived credentials. We cache the + * URL (minus an offset) so repeat queries within the window are cheap. + */ +const QUERY_URL_EXPIRATION_SECONDS = 60 * 60; +const QUERY_URL_CACHE_OFFSET_SECONDS = 60 * 5; + +/** Internal sentinel for an authorisation failure on a specific web. */ +class WebAuthorisationError extends Error {} + +export interface ResolveInvocationParams { + invocation: QueryInvocation; + actorId: ActorEntityUuid; + graphApi: GraphApi; + uploadProvider: FileStorageProvider; + cache: Keyv; +} + +export const resolveInvocation = async ({ + invocation, + actorId, + graphApi, + uploadProvider, + cache, +}: ResolveInvocationParams): Promise => { + const id = typeof invocation.id === "string" ? invocation.id : ""; + const queryName = invocation.query; + const webIds = invocation.webIds; + const args = invocation.args ?? {}; + + const asResult = (partial: Omit): QueryResult => ({ + id, + ...partial, + }); + + if (typeof queryName !== "string" || queryName.length === 0) { + return asResult({ status: "error", error: "Missing query name" }); + } + + const query = getQuery(queryName); + if (!query) { + return asResult({ status: "error", error: `Unknown query "${queryName}"` }); + } + + if (!Array.isArray(webIds) || webIds.length === 0) { + return asResult({ + status: "error", + error: "At least one webId is required", + }); + } + + const requiredRole = query.requiredWebRole ?? "member"; + + try { + // Authorise the actor against every web the invocation is scoped to. + for (const webId of webIds) { + const role = await getActorGroupRole( + graphApi, + { actorId }, + { actorId, actorGroupId: webId }, + ); + + if (!role) { + throw new WebAuthorisationError( + `You do not have access to web ${webId}`, + ); + } + if (requiredRole === "administrator" && role !== "administrator") { + throw new WebAuthorisationError( + `Administrator role required in web ${webId}`, + ); + } + } + + const loadArtifact = async (key: string): Promise => { + try { + return await uploadProvider.downloadDirect({ key }); + } catch { + return null; + } + }; + + const resolution = await query.resolve({ + webId: webIds[0]!, + webIds, + args, + loadArtifact, + }); + + if (resolution.status === "computing") { + return asResult({ + status: "computing", + retryAfterMs: resolution.retryAfterMs ?? 1000, + }); + } + + const artifacts = await Promise.all( + (resolution.artifacts ?? []).map(async (ref) => { + const cacheKey = `query-presign:${ref.key}`; + let url = await cache.get(cacheKey); + + if (!url) { + url = await uploadProvider.presignDownloadByKey({ + key: ref.key, + expiresInSeconds: QUERY_URL_EXPIRATION_SECONDS, + }); + + try { + await cache.set( + cacheKey, + url, + (QUERY_URL_EXPIRATION_SECONDS - QUERY_URL_CACHE_OFFSET_SECONDS) * + 1000, + ); + } catch (error) { + logger.warn( + `Could not cache presigned query URL [key=${ref.key}]: ${error}`, + ); + } + } + + return { + name: ref.name, + format: ref.format ?? "json", + url, + expiresAt: new Date( + Date.now() + QUERY_URL_EXPIRATION_SECONDS * 1000, + ).toISOString(), + }; + }), + ); + + return asResult({ status: "ready", artifacts }); + } catch (error) { + if ( + error instanceof WebAuthorisationError || + error instanceof QueryArgError || + error instanceof QueryNotFoundError || + error instanceof DatasetUnavailableError + ) { + return asResult({ status: "error", error: error.message }); + } + + logger.error( + `Unexpected error resolving query "${queryName}": ${ + error instanceof Error ? error.stack : String(error) + }`, + ); + return asResult({ status: "error", error: "Internal error" }); + } +}; diff --git a/apps/hash-api/src/query/shared/errors.ts b/apps/hash-api/src/query/shared/errors.ts new file mode 100644 index 00000000000..bafb3b4dc15 --- /dev/null +++ b/apps/hash-api/src/query/shared/errors.ts @@ -0,0 +1,34 @@ +/** + * Errors thrown while resolving a named query. The gateway maps each to an + * appropriate per-result status (the batch request itself still returns 200). + */ + +/** Invalid or missing arguments for a query (maps to `error`, client fault). */ +export class QueryArgError extends Error { + public readonly code = "INVALID_ARGS"; + + constructor(message: string) { + super(message); + this.name = "QueryArgError"; + } +} + +/** A requested entity/artifact does not exist in the resolved dataset. */ +export class QueryNotFoundError extends Error { + public readonly code = "NOT_FOUND"; + + constructor(message: string) { + super(message); + this.name = "QueryNotFoundError"; + } +} + +/** The dataset for a web/version is missing or not yet provisioned. */ +export class DatasetUnavailableError extends Error { + public readonly code = "DATASET_UNAVAILABLE"; + + constructor(message: string) { + super(message); + this.name = "DatasetUnavailableError"; + } +} diff --git a/apps/hash-api/src/query/shared/query-registry.ts b/apps/hash-api/src/query/shared/query-registry.ts new file mode 100644 index 00000000000..ee4c1379a07 --- /dev/null +++ b/apps/hash-api/src/query/shared/query-registry.ts @@ -0,0 +1,81 @@ +import type { RoleName, WebId } from "@blockprotocol/type-system"; + +/** + * Reference to a stored artifact that a named query resolves to. The gateway + * turns each into a short-lived, directly-fetchable URL. + */ +export interface ArtifactKeyRef { + /** Logical name within the query result, e.g. `"graph"`. */ + name: string; + /** Storage key, relative to the provider's default location. */ + key: string; + /** Wire format hint surfaced to the client (defaults to `"json"`). */ + format?: string; +} + +/** Context handed to a named query when resolving an invocation. */ +export interface QueryResolutionContext { + /** + * The primary web the query is scoped to. For single-web queries this is the + * (already authorised) web the artifacts live under. + */ + webId: WebId; + /** All authorised webs from the invocation (for future cross-web queries). */ + webIds: WebId[]; + /** Validated-as-an-object query arguments (may be empty). */ + args: Record; + /** + * Read a stored artifact's raw bytes by key, e.g. to load a dataset pointer + * or manifest during resolution. Returns `null` if the object is missing. + */ + loadArtifact: (key: string) => Promise; +} + +/** The outcome of resolving a single invocation. */ +export interface QueryResolution { + status: "ready" | "computing"; + /** Present when `status === "ready"`. */ + artifacts?: ArtifactKeyRef[]; + /** Present when `status === "computing"`: client poll hint. */ + retryAfterMs?: number; +} + +/** + * A server-registered query. Each query owns its own argument validation and + * (where relevant) dataset/manifest membership checks, keeping the gateway and + * registry domain-agnostic. + */ +export interface NamedQuery { + /** Unique name clients reference, e.g. `"productGraph"`. */ + name: string; + /** + * Minimum role the actor must hold in each scoped web. Defaults to `"member"` + * (any web role grants access). + */ + requiredWebRole?: RoleName; + resolve: (ctx: QueryResolutionContext) => Promise; +} + +const registry = new Map(); + +/** Register a named query. Throws if the name is already taken. */ +export const registerQuery = (query: NamedQuery): void => { + if (registry.has(query.name)) { + throw new Error(`Query "${query.name}" is already registered`); + } + registry.set(query.name, query); +}; + +export const registerQueries = (queries: readonly NamedQuery[]): void => { + for (const query of queries) { + registerQuery(query); + } +}; + +export const getQuery = (name: string): NamedQuery | undefined => + registry.get(name); + +/** Exposed for tests: clear all registered queries. */ +export const clearQueryRegistry = (): void => { + registry.clear(); +}; diff --git a/apps/hash-api/src/query/shared/storage-key.test.ts b/apps/hash-api/src/query/shared/storage-key.test.ts new file mode 100644 index 00000000000..d55bf039a6f --- /dev/null +++ b/apps/hash-api/src/query/shared/storage-key.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it } from "vitest"; + +import { QueryArgError } from "./errors"; +import { isValidSlug, optionalSlugArg, requireSlugArg } from "./storage-key"; + +describe("isValidSlug", () => { + it("accepts typical product/site/step ids", () => { + for (const slug of [ + "democat-x100-extr", + "demo-plant", + "prod_to_qa_pla", + "90000300001", + "raw_dwell_alpha_oxide", + ]) { + expect(isValidSlug(slug)).toBe(true); + } + }); + + it("rejects path-traversal and separator characters", () => { + for (const bad of [ + "..", + ".", + "../etc/passwd", + "a/b", + "a\\b", + "with space", + "", + "/leading", + ]) { + expect(isValidSlug(bad)).toBe(false); + } + }); + + it("rejects non-strings", () => { + expect(isValidSlug(undefined)).toBe(false); + expect(isValidSlug(null)).toBe(false); + expect(isValidSlug(42)).toBe(false); + expect(isValidSlug({})).toBe(false); + }); + + it("rejects over-long slugs", () => { + expect(isValidSlug("a".repeat(129))).toBe(false); + expect(isValidSlug("a".repeat(128))).toBe(true); + }); +}); + +describe("requireSlugArg", () => { + it("returns a valid slug", () => { + expect( + requireSlugArg({ productId: "democat-x100-extr" }, "productId"), + ).toBe("democat-x100-extr"); + }); + + it("throws QueryArgError for an invalid or missing slug", () => { + expect(() => requireSlugArg({ productId: "../x" }, "productId")).toThrow( + QueryArgError, + ); + expect(() => requireSlugArg({}, "productId")).toThrow(QueryArgError); + }); +}); + +describe("optionalSlugArg", () => { + it("returns undefined when absent", () => { + expect(optionalSlugArg({}, "siteId")).toBeUndefined(); + expect(optionalSlugArg({ siteId: null }, "siteId")).toBeUndefined(); + }); + + it("validates when present", () => { + expect(optionalSlugArg({ siteId: "demo-plant" }, "siteId")).toBe( + "demo-plant", + ); + expect(() => optionalSlugArg({ siteId: "a/b" }, "siteId")).toThrow( + QueryArgError, + ); + }); +}); diff --git a/apps/hash-api/src/query/shared/storage-key.ts b/apps/hash-api/src/query/shared/storage-key.ts new file mode 100644 index 00000000000..f0c2281f6a2 --- /dev/null +++ b/apps/hash-api/src/query/shared/storage-key.ts @@ -0,0 +1,39 @@ +import { QueryArgError } from "./errors"; + +/** + * Slugs are the only values interpolated into storage keys from client input. + * Restricting them to `[a-z0-9_-]` (and a bounded length) prevents path + * traversal and key-injection regardless of the underlying storage provider. + */ +const SLUG_PATTERN = /^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$/; + +export const isValidSlug = (value: unknown): value is string => + typeof value === "string" && SLUG_PATTERN.test(value); + +/** + * Read a required slug argument, throwing {@link QueryArgError} if it is missing + * or fails validation. + */ +export const requireSlugArg = ( + args: Record, + key: string, +): string => { + const value = args[key]; + if (!isValidSlug(value)) { + throw new QueryArgError( + `Argument "${key}" must be a slug matching ${SLUG_PATTERN.source}`, + ); + } + return value; +}; + +/** Read an optional slug argument; returns `undefined` if absent. */ +export const optionalSlugArg = ( + args: Record, + key: string, +): string | undefined => { + if (args[key] === undefined || args[key] === null) { + return undefined; + } + return requireSlugArg(args, key); +}; diff --git a/apps/hash-api/src/seed-data/index.ts b/apps/hash-api/src/seed-data/index.ts index 9db3c9fc39f..8d710f6fc94 100644 --- a/apps/hash-api/src/seed-data/index.ts +++ b/apps/hash-api/src/seed-data/index.ts @@ -6,7 +6,9 @@ import { } from "../graph/knowledge/system-types/org"; import { createOrgMembershipLinkEntity } from "../graph/knowledge/system-types/org-membership"; import { joinOrg } from "../graph/knowledge/system-types/user"; +import { isDevEnv, isTestEnv } from "../lib/env-config"; import { seedPages } from "./seed-pages"; +import { seedSupplyChainDemo } from "./seed-supply-chain-demo"; import { ensureUsersAreSeeded } from "./seed-users"; import type { ImpureGraphContext } from "../graph/context-types"; @@ -156,4 +158,10 @@ export const seedOrgsAndUsers = async (params: { ); } } + + // Seed the precomputed supply-chain demo dataset into the example org's web + // (dev/test only – it no-ops where the example org or vendored data are absent). + if (isDevEnv || isTestEnv) { + await seedSupplyChainDemo({ logger, context }); + } }; diff --git a/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts b/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts new file mode 100644 index 00000000000..7b02cde48fa --- /dev/null +++ b/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts @@ -0,0 +1,141 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +import { getOrgByShortname } from "../graph/knowledge/system-types/org"; +import { systemAccountId } from "../graph/system-account"; + +import type { ImpureGraphContext } from "../graph/context-types"; +import type { Logger } from "@local/hash-backend-utils/logger"; + +/** + * Vendored, web-agnostic demo dataset for the supply-chain (value-chain-timing) views. + */ +const DEMO_DATA_DIR = path.join( + path.dirname(fileURLToPath(import.meta.url)), + "supply-chain-demo", +); + +const EXAMPLE_ORG_SHORTNAME = "example-org"; +const STORAGE_NAMESPACE = "supply-chain"; + +const collectFiles = (dir: string): string[] => { + const out: string[] = []; + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + out.push(...collectFiles(full)); + } else if (entry.isFile() && entry.name.endsWith(".json")) { + out.push(full); + } + } + return out; +}; + +/** The `datasetVersion` of the vendored dataset, or `null` if unreadable. */ +const readVendoredDatasetVersion = (): string | null => { + try { + const raw = fs.readFileSync( + path.join(DEMO_DATA_DIR, "current.json"), + "utf8", + ); + const parsed = JSON.parse(raw) as { datasetVersion?: unknown }; + return typeof parsed.datasetVersion === "string" + ? parsed.datasetVersion + : null; + } catch { + return null; + } +}; + +/** + * Upload the vendored supply-chain demo dataset into the `@example-org` web's + * storage namespace so the query gateway can serve it to seeded users. + * + * Safe to call on every boot: + * - no-ops in environments without the example org (e.g. production) or without + * vendored data; + * - skips when the web already has this `datasetVersion` seeded (so reboots are + * cheap), and otherwise re-uploads. Storage keys are deterministic, so an + * upload overwrites the existing object rather than creating duplicates. + */ +export const seedSupplyChainDemo = async (params: { + logger: Logger; + context: ImpureGraphContext; +}): Promise => { + const { logger, context } = params; + + if (!fs.existsSync(DEMO_DATA_DIR)) { + logger.info("No supply-chain demo data vendored; skipping demo seed."); + return; + } + + const { uploadProvider } = context; + if (!uploadProvider) { + logger.warn( + "No upload provider available; skipping supply-chain demo seed.", + ); + return; + } + + const org = await getOrgByShortname( + context, + { actorId: systemAccountId }, + { shortname: EXAMPLE_ORG_SHORTNAME }, + ); + + if (!org) { + logger.info( + `No "${EXAMPLE_ORG_SHORTNAME}" org found; skipping supply-chain demo seed.`, + ); + return; + } + + const { webId } = org; + const currentKey = `${STORAGE_NAMESPACE}/${webId}/current.json`; + const vendoredVersion = readVendoredDatasetVersion(); + + // Idempotency: if this web already has the vendored version seeded, skip the + // re-upload entirely. (Bumping `datasetVersion` falls through and re-seeds.) + if (vendoredVersion) { + try { + const existing = await uploadProvider.downloadDirect({ key: currentKey }); + const parsed = JSON.parse(existing.toString("utf8")) as { + datasetVersion?: unknown; + }; + if (parsed.datasetVersion === vendoredVersion) { + logger.info( + `Supply-chain demo dataset v${vendoredVersion} already seeded into web ${webId}; skipping.`, + ); + return; + } + } catch { + // Not seeded yet (or pointer unreadable) — fall through and upload. + } + } + + const files = collectFiles(DEMO_DATA_DIR); + let uploaded = 0; + + for (const absPath of files) { + const relKey = path + .relative(DEMO_DATA_DIR, absPath) + .split(path.sep) + .join("/"); + const key = `${STORAGE_NAMESPACE}/${webId}/${relKey}`; + + const body = await fs.promises.readFile(absPath); + await uploadProvider.uploadDirect({ + key, + body, + contentType: "application/json", + }); + uploaded += 1; + } + + logger.info( + `Seeded supply-chain demo dataset${ + vendoredVersion ? ` v${vendoredVersion}` : "" + } into web ${webId} (${uploaded} files).`, + ); +}; diff --git a/apps/hash-api/src/seed-data/seed-users.ts b/apps/hash-api/src/seed-data/seed-users.ts index 80e24b1c879..41081a99b3e 100644 --- a/apps/hash-api/src/seed-data/seed-users.ts +++ b/apps/hash-api/src/seed-data/seed-users.ts @@ -41,6 +41,8 @@ const devUsers: readonly SeededUser[] = [ email: "bob@example.com", shortname: "bob01", displayName: "Bob", + // Bob exercises the supply-chain views without the full feature set. + enabledFeatureFlags: ["supplyChain"], }, ] as const; diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier-lines.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier-lines.json new file mode 100644 index 00000000000..11aa305b6c3 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier-lines.json @@ -0,0 +1,3046 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-06-17T16:36:56Z", + "lines": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000000", + "po_item": "00010", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "first_gr_date": "2025-06-06", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000001", + "po_item": "00020", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "first_gr_date": "2025-06-15", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000002", + "po_item": "00030", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "first_gr_date": "2025-06-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000003", + "po_item": "00040", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "first_gr_date": "2025-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000004", + "po_item": "00050", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "first_gr_date": "2025-06-21", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000005", + "po_item": "00010", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "first_gr_date": "2025-06-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000006", + "po_item": "00020", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "first_gr_date": "2025-07-09", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000008", + "po_item": "00040", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000009", + "po_item": "00050", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "first_gr_date": "2025-07-21", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000010", + "po_item": "00010", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "first_gr_date": "2025-07-26", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000012", + "po_item": "00030", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000013", + "po_item": "00040", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "first_gr_date": "2025-08-20", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000014", + "po_item": "00050", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "first_gr_date": "2025-08-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000015", + "po_item": "00010", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "first_gr_date": "2025-08-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000016", + "po_item": "00020", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "first_gr_date": "2025-09-25", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000017", + "po_item": "00030", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "first_gr_date": "2025-10-05", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000018", + "po_item": "00040", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "first_gr_date": "2025-10-10", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000019", + "po_item": "00050", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "first_gr_date": "2025-09-27", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000020", + "po_item": "00010", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "first_gr_date": "2025-10-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000021", + "po_item": "00020", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "first_gr_date": "2025-10-19", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000022", + "po_item": "00030", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "first_gr_date": "2025-10-16", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000023", + "po_item": "00040", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-31", + "days_late": 2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000024", + "po_item": "00050", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "first_gr_date": "2025-11-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000025", + "po_item": "00010", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "first_gr_date": "2025-11-17", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000026", + "po_item": "00020", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "first_gr_date": "2025-12-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000027", + "po_item": "00030", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "first_gr_date": "2025-11-29", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000028", + "po_item": "00040", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "first_gr_date": "2025-12-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000029", + "po_item": "00050", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "first_gr_date": "2025-12-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000030", + "po_item": "00010", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-24", + "days_late": 1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000031", + "po_item": "00020", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000032", + "po_item": "00030", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "first_gr_date": "2026-01-17", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000033", + "po_item": "00040", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000034", + "po_item": "00050", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000035", + "po_item": "00010", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000036", + "po_item": "00020", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "first_gr_date": "2026-01-31", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000037", + "po_item": "00030", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "first_gr_date": "2026-02-08", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000038", + "po_item": "00040", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000039", + "po_item": "00050", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "first_gr_date": "2026-03-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000040", + "po_item": "00010", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "first_gr_date": "2026-02-25", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000041", + "po_item": "00020", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000042", + "po_item": "00030", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "first_gr_date": "2026-03-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000043", + "po_item": "00040", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "first_gr_date": "2026-03-22", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000044", + "po_item": "00050", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000045", + "po_item": "00010", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000047", + "po_item": "00030", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-01", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000048", + "po_item": "00040", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "first_gr_date": "2026-04-22", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000049", + "po_item": "00050", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "first_gr_date": "2026-05-06", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000050", + "po_item": "00010", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "first_gr_date": "2026-04-27", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000051", + "po_item": "00020", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000052", + "po_item": "00030", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000053", + "po_item": "00040", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-29", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000054", + "po_item": "00050", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "first_gr_date": "2026-06-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000055", + "po_item": "00010", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "first_gr_date": "2026-06-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000056", + "po_item": "00010", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "first_gr_date": "2026-04-10", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000057", + "po_item": "00020", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "first_gr_date": "2026-04-01", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000059", + "po_item": "00040", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000060", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-14", + "days_late": 1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000061", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-18", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000062", + "po_item": "00020", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000063", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "first_gr_date": "2026-05-07", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000064", + "po_item": "00040", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-05", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000065", + "po_item": "00050", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "first_gr_date": "2026-05-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000066", + "po_item": "00010", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000071", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000074", + "po_item": "00020", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "first_gr_date": "2026-05-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000075", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-15", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000076", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000077", + "po_item": "00050", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "first_gr_date": "2026-06-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000078", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-03", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000079", + "po_item": "00020", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "first_gr_date": "2026-06-09", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000080", + "po_item": "00010", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "first_gr_date": "2025-09-08", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000081", + "po_item": "00020", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "first_gr_date": "2025-08-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000082", + "po_item": "00030", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "first_gr_date": "2025-09-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000083", + "po_item": "00040", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "first_gr_date": "2025-09-16", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000084", + "po_item": "00050", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "first_gr_date": "2025-10-01", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000085", + "po_item": "00010", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "first_gr_date": "2025-10-19", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000086", + "po_item": "00020", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000087", + "po_item": "00030", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "first_gr_date": "2025-10-22", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000088", + "po_item": "00040", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000089", + "po_item": "00050", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-01", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000090", + "po_item": "00010", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-06", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000091", + "po_item": "00020", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "first_gr_date": "2025-11-30", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000092", + "po_item": "00030", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "first_gr_date": "2025-12-07", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000093", + "po_item": "00040", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "first_gr_date": "2025-11-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000094", + "po_item": "00050", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "first_gr_date": "2025-11-25", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000095", + "po_item": "00010", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-20", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000096", + "po_item": "00020", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000097", + "po_item": "00030", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "first_gr_date": "2025-12-30", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000098", + "po_item": "00040", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000099", + "po_item": "00050", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "first_gr_date": "2025-12-27", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000100", + "po_item": "00010", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000101", + "po_item": "00020", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000102", + "po_item": "00030", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000103", + "po_item": "00040", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-13", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000104", + "po_item": "00050", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "first_gr_date": "2026-02-08", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000105", + "po_item": "00010", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "first_gr_date": "2026-02-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000106", + "po_item": "00020", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "first_gr_date": "2026-03-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000107", + "po_item": "00030", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "first_gr_date": "2026-03-02", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000108", + "po_item": "00040", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000109", + "po_item": "00050", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000110", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-25", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000111", + "po_item": "00020", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "first_gr_date": "2026-04-12", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000112", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-13", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000113", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "first_gr_date": "2026-05-01", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000114", + "po_item": "00050", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-11", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000115", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "first_gr_date": "2026-04-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000116", + "po_item": "00020", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-21", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000117", + "po_item": "00030", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "first_gr_date": "2026-05-05", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000118", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "first_gr_date": "2026-05-31", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000119", + "po_item": "00050", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "first_gr_date": "2026-06-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000120", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "first_gr_date": "2026-06-05", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000121", + "po_item": "00020", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "first_gr_date": "2026-06-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000122", + "po_item": "00010", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000123", + "po_item": "00020", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000124", + "po_item": "00030", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-07", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000125", + "po_item": "00040", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "first_gr_date": "2026-02-24", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000126", + "po_item": "00050", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "first_gr_date": "2026-03-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000127", + "po_item": "00010", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-23", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000128", + "po_item": "00020", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000129", + "po_item": "00030", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-08", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000130", + "po_item": "00040", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "first_gr_date": "2026-04-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000131", + "po_item": "00050", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000132", + "po_item": "00010", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000133", + "po_item": "00020", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "first_gr_date": "2026-05-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000134", + "po_item": "00030", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "first_gr_date": "2026-04-30", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000135", + "po_item": "00040", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000136", + "po_item": "00050", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "first_gr_date": "2026-05-08", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000137", + "po_item": "00010", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "first_gr_date": "2026-06-01", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000138", + "po_item": "00020", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "first_gr_date": "2026-05-28", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000139", + "po_item": "00030", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "first_gr_date": "2026-05-31", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000141", + "po_item": "00020", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000142", + "po_item": "00030", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-29", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000143", + "po_item": "00040", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000144", + "po_item": "00050", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "first_gr_date": "2025-11-10", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000145", + "po_item": "00010", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "first_gr_date": "2025-12-11", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000146", + "po_item": "00020", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "first_gr_date": "2025-12-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000147", + "po_item": "00030", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000148", + "po_item": "00040", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "first_gr_date": "2025-12-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000149", + "po_item": "00050", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "first_gr_date": "2026-01-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000150", + "po_item": "00010", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "first_gr_date": "2026-01-06", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000151", + "po_item": "00020", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "first_gr_date": "2026-01-13", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000152", + "po_item": "00030", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "first_gr_date": "2026-01-26", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000153", + "po_item": "00040", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000154", + "po_item": "00050", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "first_gr_date": "2026-01-31", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000155", + "po_item": "00010", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000156", + "po_item": "00020", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "first_gr_date": "2026-02-14", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000157", + "po_item": "00030", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000158", + "po_item": "00040", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "first_gr_date": "2026-02-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000159", + "po_item": "00050", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "first_gr_date": "2026-03-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000160", + "po_item": "00010", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "first_gr_date": "2026-03-08", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000163", + "po_item": "00040", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000164", + "po_item": "00050", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-09", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000165", + "po_item": "00010", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000166", + "po_item": "00020", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-10", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000167", + "po_item": "00030", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000168", + "po_item": "00040", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "first_gr_date": "2026-04-30", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000169", + "po_item": "00050", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000170", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-27", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000171", + "po_item": "00020", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "first_gr_date": "2026-05-11", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000172", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "first_gr_date": "2026-06-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000174", + "po_item": "00050", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "first_gr_date": "2026-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000175", + "po_item": "00010", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000176", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000178", + "po_item": "00040", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-19", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000179", + "po_item": "00050", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "first_gr_date": "2026-03-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000180", + "po_item": "00010", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "first_gr_date": "2026-04-02", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000181", + "po_item": "00020", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "first_gr_date": "2026-04-24", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000182", + "po_item": "00030", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "first_gr_date": "2026-04-25", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000183", + "po_item": "00040", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-26", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000184", + "po_item": "00050", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "first_gr_date": "2026-05-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000185", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000187", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "first_gr_date": "2026-06-18", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000188", + "po_item": "00040", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "first_gr_date": "2026-06-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + } + ] +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier_performance.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier_performance.json new file mode 100644 index 00000000000..f3dc980820f --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/_global/supplier_performance.json @@ -0,0 +1,716 @@ +{ + "generated_at": "2026-06-17T16:36:56Z", + "overall": { + "n_lines": 190, + "n_vendors": 6, + "on_time_pct": 88.9, + "in_full_pct": 100.0, + "otif_pct": 88.9, + "coverage_pct": 100.0, + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "min_lines_for_leaderboard": 3 + }, + "vendors": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "n_lines": 56, + "n_late": 5, + "on_time_pct": 91.1, + "in_full_pct": 100.0, + "otif_pct": 91.1, + "mean_days_late_all": 0.29, + "mean_days_late_when_late": 3.2, + "median_days_late_when_late": 3, + "max_days_late": 6, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 8.9, + "ge_3d_pct": 5.4, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + }, + "monthly": [ + { + "month": "2025-06", + "n": 6, + "on_time_pct": 100.0 + }, + { + "month": "2025-07", + "n": 4, + "on_time_pct": 75.0 + }, + { + "month": "2025-08", + "n": 6, + "on_time_pct": 83.3 + }, + { + "month": "2025-09", + "n": 2, + "on_time_pct": 100.0 + }, + { + "month": "2025-10", + "n": 6, + "on_time_pct": 83.3 + }, + { + "month": "2025-11", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2025-12", + "n": 4, + "on_time_pct": 75.0 + }, + { + "month": "2026-01", + "n": 6, + "on_time_pct": 100.0 + }, + { + "month": "2026-02", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2026-03", + "n": 6, + "on_time_pct": 100.0 + }, + { + "month": "2026-04", + "n": 3, + "on_time_pct": 66.7 + }, + { + "month": "2026-05", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-06", + "n": 3, + "on_time_pct": 100.0 + } + ], + "materials": [ + { + "matnr": "demo_highland_arabica", + "name": "Highland Arabica", + "n_lines": 56, + "on_time_pct": 91.1, + "otif_pct": 91.1 + } + ], + "worst_events": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000023", + "po_item": "00040", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-31", + "days_late": 2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000030", + "po_item": "00010", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-24", + "days_late": 1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + } + ] + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "n_lines": 42, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + }, + "monthly": [ + { + "month": "2025-08", + "n": 1, + "on_time_pct": 100.0 + }, + { + "month": "2025-09", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2025-10", + "n": 5, + "on_time_pct": 100.0 + }, + { + "month": "2025-11", + "n": 5, + "on_time_pct": 100.0 + }, + { + "month": "2025-12", + "n": 6, + "on_time_pct": 100.0 + }, + { + "month": "2026-01", + "n": 2, + "on_time_pct": 100.0 + }, + { + "month": "2026-02", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-03", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-04", + "n": 5, + "on_time_pct": 100.0 + }, + { + "month": "2026-05", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-06", + "n": 3, + "on_time_pct": 100.0 + } + ], + "materials": [ + { + "matnr": "demo_lowland_robusta", + "name": "Lowland Robusta", + "n_lines": 42, + "on_time_pct": 100.0, + "otif_pct": 100.0 + } + ], + "worst_events": [] + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "n_lines": 35, + "n_late": 4, + "on_time_pct": 88.6, + "in_full_pct": 100.0, + "otif_pct": 88.6, + "mean_days_late_all": 1.29, + "mean_days_late_when_late": 11.2, + "median_days_late_when_late": 10.0, + "max_days_late": 24, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 11.4, + "ge_3d_pct": 8.6, + "ge_7d_pct": 8.6, + "ge_14d_pct": 2.9 + }, + "monthly": [ + { + "month": "2025-10", + "n": 1, + "on_time_pct": 100.0 + }, + { + "month": "2025-11", + "n": 4, + "on_time_pct": 75.0 + }, + { + "month": "2025-12", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-01", + "n": 7, + "on_time_pct": 100.0 + }, + { + "month": "2026-02", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2026-03", + "n": 3, + "on_time_pct": 66.7 + }, + { + "month": "2026-04", + "n": 7, + "on_time_pct": 85.7 + }, + { + "month": "2026-05", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2026-06", + "n": 2, + "on_time_pct": 100.0 + }, + { + "month": "2026-07", + "n": 1, + "on_time_pct": 0.0 + } + ], + "materials": [ + { + "matnr": "demo_washed_bourbon", + "name": "Washed Bourbon", + "n_lines": 35, + "on_time_pct": 88.6, + "otif_pct": 88.6 + } + ], + "worst_events": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + } + ] + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 27, + "n_late": 7, + "on_time_pct": 74.1, + "in_full_pct": 100.0, + "otif_pct": 74.1, + "mean_days_late_all": 1.22, + "mean_days_late_when_late": 4.7, + "median_days_late_when_late": 2, + "max_days_late": 18, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 25.9, + "ge_3d_pct": 11.1, + "ge_7d_pct": 3.7, + "ge_14d_pct": 3.7 + }, + "monthly": [ + { + "month": "2026-03", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-04", + "n": 9, + "on_time_pct": 55.6 + }, + { + "month": "2026-05", + "n": 7, + "on_time_pct": 100.0 + }, + { + "month": "2026-06", + "n": 7, + "on_time_pct": 57.1 + } + ], + "materials": [ + { + "matnr": "demo_washed_bourbon", + "name": "Washed Bourbon", + "n_lines": 15, + "on_time_pct": 80.0, + "otif_pct": 80.0 + }, + { + "matnr": "demo_highland_arabica", + "name": "Highland Arabica", + "n_lines": 12, + "on_time_pct": 66.7, + "otif_pct": 66.7 + } + ], + "worst_events": [ + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000056", + "po_item": "00010", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "first_gr_date": "2026-04-10", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + } + ] + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "n_lines": 18, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + }, + "monthly": [ + { + "month": "2026-02", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2026-03", + "n": 4, + "on_time_pct": 100.0 + }, + { + "month": "2026-04", + "n": 3, + "on_time_pct": 100.0 + }, + { + "month": "2026-05", + "n": 7, + "on_time_pct": 100.0 + }, + { + "month": "2026-06", + "n": 1, + "on_time_pct": 100.0 + } + ], + "materials": [ + { + "matnr": "demo_lowland_robusta", + "name": "Lowland Robusta", + "n_lines": 18, + "on_time_pct": 100.0, + "otif_pct": 100.0 + } + ], + "worst_events": [] + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "n_lines": 12, + "n_late": 5, + "on_time_pct": 58.3, + "in_full_pct": 100.0, + "otif_pct": 58.3, + "mean_days_late_all": 6.25, + "mean_days_late_when_late": 15, + "median_days_late_when_late": 18, + "max_days_late": 30, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 41.7, + "ge_3d_pct": 41.7, + "ge_7d_pct": 25.0, + "ge_14d_pct": 25.0 + }, + "monthly": [ + { + "month": "2026-04", + "n": 3, + "on_time_pct": 33.3 + }, + { + "month": "2026-05", + "n": 4, + "on_time_pct": 50.0 + }, + { + "month": "2026-06", + "n": 5, + "on_time_pct": 80.0 + } + ], + "materials": [ + { + "matnr": "demo_highland_arabica", + "name": "Highland Arabica", + "n_lines": 12, + "on_time_pct": 58.3, + "otif_pct": 58.3 + } + ], + "worst_events": [ + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + } + ] + } + ], + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/graph.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/graph.json new file mode 100644 index 00000000000..4fe2b74569c --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/graph.json @@ -0,0 +1,16588 @@ +{ + "product_id": "harbor-dark-roast", + "product_name": "Harbor Dark Roast", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 40.2, + "median": 40.0, + "std": 13.3, + "min": 8, + "max": 105, + "p25": 35.0, + "p75": 45.0, + "p85": 48.0, + "p95": 55.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 55 + }, + { + "date": "2022-06-10", + "value": 42 + }, + { + "date": "2022-09-22", + "value": 8 + }, + { + "date": "2022-12-05", + "value": 63 + }, + { + "date": "2023-02-14", + "value": 38 + }, + { + "date": "2023-05-30", + "value": 22 + }, + { + "date": "2023-08-17", + "value": 71 + }, + { + "date": "2023-11-02", + "value": 30 + }, + { + "date": "2024-01-25", + "value": 45 + }, + { + "date": "2024-04-11", + "value": 18 + }, + { + "date": "2024-07-09", + "value": 105 + }, + { + "date": "2024-10-03", + "value": 35 + }, + { + "date": "2025-01-20", + "value": 12 + }, + { + "date": "2025-04-08", + "value": 48 + }, + { + "date": "2025-09-05", + "value": 39 + }, + { + "date": "2025-09-11", + "value": 41 + }, + { + "date": "2025-09-17", + "value": 44 + }, + { + "date": "2025-09-23", + "value": 48 + }, + { + "date": "2025-09-29", + "value": 51 + }, + { + "date": "2025-10-06", + "value": 37 + }, + { + "date": "2025-10-12", + "value": 40 + }, + { + "date": "2025-10-18", + "value": 44 + }, + { + "date": "2025-10-24", + "value": 47 + }, + { + "date": "2025-10-30", + "value": 31 + }, + { + "date": "2025-11-04", + "value": 36 + }, + { + "date": "2025-11-10", + "value": 40 + }, + { + "date": "2025-11-16", + "value": 43 + }, + { + "date": "2025-11-22", + "value": 27 + }, + { + "date": "2025-11-28", + "value": 31 + }, + { + "date": "2025-12-05", + "value": 46 + }, + { + "date": "2025-12-11", + "value": 49 + }, + { + "date": "2025-12-17", + "value": 33 + }, + { + "date": "2025-12-23", + "value": 37 + }, + { + "date": "2025-12-29", + "value": 39 + }, + { + "date": "2026-01-06", + "value": 45 + }, + { + "date": "2026-01-12", + "value": 29 + }, + { + "date": "2026-01-18", + "value": 33 + }, + { + "date": "2026-01-24", + "value": 35 + }, + { + "date": "2026-01-30", + "value": 38 + }, + { + "date": "2026-02-04", + "value": 35 + }, + { + "date": "2026-02-10", + "value": 39 + }, + { + "date": "2026-02-16", + "value": 41 + }, + { + "date": "2026-02-22", + "value": 44 + }, + { + "date": "2026-02-28", + "value": 48 + }, + { + "date": "2026-03-05", + "value": 35 + }, + { + "date": "2026-03-11", + "value": 37 + }, + { + "date": "2026-03-17", + "value": 40 + }, + { + "date": "2026-03-23", + "value": 44 + }, + { + "date": "2026-03-29", + "value": 47 + }, + { + "date": "2026-04-06", + "value": 33 + }, + { + "date": "2026-04-12", + "value": 36 + }, + { + "date": "2026-04-18", + "value": 40 + }, + { + "date": "2026-04-24", + "value": 43 + }, + { + "date": "2026-04-30", + "value": 27 + }, + { + "date": "2026-05-04", + "value": 42 + }, + { + "date": "2026-05-10", + "value": 46 + }, + { + "date": "2026-05-16", + "value": 49 + }, + { + "date": "2026-05-22", + "value": 33 + }, + { + "date": "2026-05-28", + "value": 37 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1 + }, + { + "month": "2022-09", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2022-12", + "mean": 63.0, + "median": 63.0, + "p10": 63.0, + "p25": 63.0, + "p75": 63.0, + "p90": 63.0, + "n": 1 + }, + { + "month": "2023-02", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 71.0, + "median": 71.0, + "p10": 71.0, + "p25": 71.0, + "p75": 71.0, + "p90": 71.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 45.0, + "median": 45.0, + "p10": 45.0, + "p25": 45.0, + "p75": 45.0, + "p90": 45.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 105.0, + "median": 105.0, + "p10": 105.0, + "p25": 105.0, + "p75": 105.0, + "p90": 105.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 44.6, + "median": 44.0, + "p10": 39.8, + "p25": 41.0, + "p75": 48.0, + "p90": 49.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 39.8, + "median": 40.0, + "p10": 33.4, + "p25": 37.0, + "p75": 44.0, + "p90": 45.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 35.4, + "median": 36.0, + "p10": 28.6, + "p25": 31.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 40.8, + "median": 39.0, + "p10": 34.6, + "p25": 37.0, + "p75": 46.0, + "p90": 47.8, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.0, + "median": 35.0, + "p10": 30.6, + "p25": 33.0, + "p75": 38.0, + "p90": 42.2, + "n": 5 + }, + { + "month": "2026-02", + "mean": 41.4, + "median": 41.0, + "p10": 36.6, + "p25": 39.0, + "p75": 44.0, + "p90": 46.4, + "n": 5 + }, + { + "month": "2026-03", + "mean": 40.6, + "median": 40.0, + "p10": 35.8, + "p25": 37.0, + "p75": 44.0, + "p90": 45.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 35.8, + "median": 36.0, + "p10": 29.4, + "p25": 33.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2026-05", + "mean": 41.4, + "median": 42.0, + "p10": 34.6, + "p25": 37.0, + "p75": 46.0, + "p90": 47.8, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 33.4, + "median": 33.0, + "std": 11.4, + "min": 5, + "max": 82, + "p25": 28.0, + "p75": 38.0, + "p85": 40.7, + "p95": 51.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 32 + }, + { + "date": "2022-04-19", + "value": 48 + }, + { + "date": "2022-07-11", + "value": 5 + }, + { + "date": "2022-09-28", + "value": 67 + }, + { + "date": "2022-12-15", + "value": 25 + }, + { + "date": "2023-03-07", + "value": 41 + }, + { + "date": "2023-05-22", + "value": 15 + }, + { + "date": "2023-08-09", + "value": 82 + }, + { + "date": "2023-10-30", + "value": 38 + }, + { + "date": "2024-01-16", + "value": 20 + }, + { + "date": "2024-03-25", + "value": 52 + }, + { + "date": "2024-06-12", + "value": 10 + }, + { + "date": "2024-08-28", + "value": 44 + }, + { + "date": "2024-11-14", + "value": 28 + }, + { + "date": "2025-01-06", + "value": 35 + }, + { + "date": "2025-03-18", + "value": 18 + }, + { + "date": "2025-05-29", + "value": 55 + }, + { + "date": "2025-08-12", + "value": 26 + }, + { + "date": "2025-09-04", + "value": 26 + }, + { + "date": "2025-09-10", + "value": 29 + }, + { + "date": "2025-09-16", + "value": 31 + }, + { + "date": "2025-09-22", + "value": 34 + }, + { + "date": "2025-09-28", + "value": 37 + }, + { + "date": "2025-10-05", + "value": 26 + }, + { + "date": "2025-10-11", + "value": 28 + }, + { + "date": "2025-10-17", + "value": 31 + }, + { + "date": "2025-10-23", + "value": 33 + }, + { + "date": "2025-10-29", + "value": 36 + }, + { + "date": "2025-11-06", + "value": 33 + }, + { + "date": "2025-11-12", + "value": 36 + }, + { + "date": "2025-11-18", + "value": 38 + }, + { + "date": "2025-11-24", + "value": 42 + }, + { + "date": "2025-11-30", + "value": 28 + }, + { + "date": "2025-12-04", + "value": 32 + }, + { + "date": "2025-12-10", + "value": 35 + }, + { + "date": "2025-12-16", + "value": 38 + }, + { + "date": "2025-12-22", + "value": 24 + }, + { + "date": "2025-12-28", + "value": 28 + }, + { + "date": "2026-01-05", + "value": 40 + }, + { + "date": "2026-01-11", + "value": 43 + }, + { + "date": "2026-01-17", + "value": 29 + }, + { + "date": "2026-01-23", + "value": 33 + }, + { + "date": "2026-01-29", + "value": 35 + }, + { + "date": "2026-02-06", + "value": 40 + }, + { + "date": "2026-02-12", + "value": 26 + }, + { + "date": "2026-02-18", + "value": 29 + }, + { + "date": "2026-02-24", + "value": 31 + }, + { + "date": "2026-02-30", + "value": 34 + }, + { + "date": "2026-03-04", + "value": 22 + }, + { + "date": "2026-03-10", + "value": 26 + }, + { + "date": "2026-03-16", + "value": 28 + }, + { + "date": "2026-03-22", + "value": 31 + }, + { + "date": "2026-03-28", + "value": 33 + }, + { + "date": "2026-04-05", + "value": 31 + }, + { + "date": "2026-04-11", + "value": 33 + }, + { + "date": "2026-04-17", + "value": 36 + }, + { + "date": "2026-04-23", + "value": 38 + }, + { + "date": "2026-04-29", + "value": 42 + }, + { + "date": "2026-05-06", + "value": 30 + }, + { + "date": "2026-05-12", + "value": 32 + }, + { + "date": "2026-05-18", + "value": 35 + }, + { + "date": "2026-05-24", + "value": 38 + }, + { + "date": "2026-05-30", + "value": 24 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 32.0, + "median": 32.0, + "p10": 32.0, + "p25": 32.0, + "p75": 32.0, + "p90": 32.0, + "n": 1 + }, + { + "month": "2022-04", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-09", + "mean": 67.0, + "median": 67.0, + "p10": 67.0, + "p25": 67.0, + "p75": 67.0, + "p90": 67.0, + "n": 1 + }, + { + "month": "2022-12", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 41.0, + "median": 41.0, + "p10": 41.0, + "p25": 41.0, + "p75": 41.0, + "p90": 41.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 82.0, + "median": 82.0, + "p10": 82.0, + "p25": 82.0, + "p75": 82.0, + "p90": 82.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 20.0, + "median": 20.0, + "p10": 20.0, + "p25": 20.0, + "p75": 20.0, + "p90": 20.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 52.0, + "median": 52.0, + "p10": 52.0, + "p25": 52.0, + "p75": 52.0, + "p90": 52.0, + "n": 1 + }, + { + "month": "2024-06", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1 + }, + { + "month": "2024-08", + "mean": 44.0, + "median": 44.0, + "p10": 44.0, + "p25": 44.0, + "p75": 44.0, + "p90": 44.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 31.4, + "median": 31.0, + "p10": 27.2, + "p25": 29.0, + "p75": 34.0, + "p90": 35.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 30.8, + "median": 31.0, + "p10": 26.8, + "p25": 28.0, + "p75": 33.0, + "p90": 34.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 35.4, + "median": 36.0, + "p10": 30.0, + "p25": 33.0, + "p75": 38.0, + "p90": 40.4, + "n": 5 + }, + { + "month": "2025-12", + "mean": 31.4, + "median": 32.0, + "p10": 25.6, + "p25": 28.0, + "p75": 35.0, + "p90": 36.8, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.0, + "median": 35.0, + "p10": 30.6, + "p25": 33.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 32.0, + "median": 31.0, + "p10": 27.2, + "p25": 29.0, + "p75": 34.0, + "p90": 37.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 28.0, + "median": 28.0, + "p10": 23.6, + "p25": 26.0, + "p75": 31.0, + "p90": 32.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 36.0, + "median": 36.0, + "p10": 31.8, + "p25": 33.0, + "p75": 38.0, + "p90": 40.4, + "n": 5 + }, + { + "month": "2026-05", + "mean": 31.8, + "median": 32.0, + "p10": 26.4, + "p25": 30.0, + "p75": 35.0, + "p90": 36.8, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 26.1, + "median": 25.0, + "std": 8.0, + "min": 7, + "max": 62, + "p25": 22.5, + "p75": 29.0, + "p85": 30.0, + "p95": 36.5 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 35 + }, + { + "date": "2022-10-18", + "value": 16 + }, + { + "date": "2023-01-24", + "value": 62 + }, + { + "date": "2023-06-15", + "value": 7 + }, + { + "date": "2023-09-28", + "value": 40 + }, + { + "date": "2024-02-12", + "value": 25 + }, + { + "date": "2024-05-07", + "value": 48 + }, + { + "date": "2024-09-19", + "value": 12 + }, + { + "date": "2025-02-04", + "value": 30 + }, + { + "date": "2025-06-10", + "value": 14 + }, + { + "date": "2025-09-06", + "value": 30 + }, + { + "date": "2025-09-12", + "value": 19 + }, + { + "date": "2025-09-18", + "value": 22 + }, + { + "date": "2025-09-24", + "value": 23 + }, + { + "date": "2025-09-30", + "value": 25 + }, + { + "date": "2025-10-04", + "value": 23 + }, + { + "date": "2025-10-10", + "value": 25 + }, + { + "date": "2025-10-16", + "value": 27 + }, + { + "date": "2025-10-22", + "value": 29 + }, + { + "date": "2025-10-28", + "value": 31 + }, + { + "date": "2025-11-05", + "value": 23 + }, + { + "date": "2025-11-11", + "value": 25 + }, + { + "date": "2025-11-17", + "value": 27 + }, + { + "date": "2025-11-23", + "value": 29 + }, + { + "date": "2025-11-29", + "value": 31 + }, + { + "date": "2025-12-06", + "value": 22 + }, + { + "date": "2025-12-12", + "value": 24 + }, + { + "date": "2025-12-18", + "value": 26 + }, + { + "date": "2025-12-24", + "value": 28 + }, + { + "date": "2025-12-30", + "value": 18 + }, + { + "date": "2026-01-04", + "value": 28 + }, + { + "date": "2026-01-10", + "value": 30 + }, + { + "date": "2026-01-16", + "value": 32 + }, + { + "date": "2026-01-22", + "value": 22 + }, + { + "date": "2026-01-28", + "value": 24 + }, + { + "date": "2026-02-05", + "value": 27 + }, + { + "date": "2026-02-11", + "value": 30 + }, + { + "date": "2026-02-17", + "value": 19 + }, + { + "date": "2026-02-23", + "value": 22 + }, + { + "date": "2026-02-29", + "value": 23 + }, + { + "date": "2026-03-06", + "value": 34 + }, + { + "date": "2026-03-12", + "value": 23 + }, + { + "date": "2026-03-18", + "value": 25 + }, + { + "date": "2026-03-24", + "value": 27 + }, + { + "date": "2026-03-30", + "value": 29 + }, + { + "date": "2026-04-04", + "value": 20 + }, + { + "date": "2026-04-10", + "value": 23 + }, + { + "date": "2026-04-16", + "value": 25 + }, + { + "date": "2026-04-22", + "value": 27 + }, + { + "date": "2026-04-28", + "value": 29 + }, + { + "date": "2026-05-05", + "value": 20 + }, + { + "date": "2026-05-11", + "value": 22 + }, + { + "date": "2026-05-17", + "value": 24 + }, + { + "date": "2026-05-23", + "value": 26 + }, + { + "date": "2026-05-29", + "value": 28 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 16.0, + "median": 16.0, + "p10": 16.0, + "p25": 16.0, + "p75": 16.0, + "p90": 16.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 62.0, + "median": 62.0, + "p10": 62.0, + "p25": 62.0, + "p75": 62.0, + "p90": 62.0, + "n": 1 + }, + { + "month": "2023-06", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 40.0, + "median": 40.0, + "p10": 40.0, + "p25": 40.0, + "p75": 40.0, + "p90": 40.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2025-02", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 14.0, + "median": 14.0, + "p10": 14.0, + "p25": 14.0, + "p75": 14.0, + "p90": 14.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 23.8, + "median": 23.0, + "p10": 20.2, + "p25": 22.0, + "p75": 25.0, + "p90": 28.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 27.0, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 30.2, + "n": 5 + }, + { + "month": "2025-11", + "mean": 27.0, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 30.2, + "n": 5 + }, + { + "month": "2025-12", + "mean": 23.6, + "median": 24.0, + "p10": 19.6, + "p25": 22.0, + "p75": 26.0, + "p90": 27.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 27.2, + "median": 28.0, + "p10": 22.8, + "p25": 24.0, + "p75": 30.0, + "p90": 31.2, + "n": 5 + }, + { + "month": "2026-02", + "mean": 24.2, + "median": 23.0, + "p10": 20.2, + "p25": 22.0, + "p75": 27.0, + "p90": 28.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 27.6, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 32.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 24.8, + "median": 25.0, + "p10": 21.2, + "p25": 23.0, + "p75": 27.0, + "p90": 28.2, + "n": 5 + }, + { + "month": "2026-05", + "mean": 24.0, + "median": 24.0, + "p10": 20.8, + "p25": 22.0, + "p75": 26.0, + "p90": 27.2, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 48.3, + "median": 46.0, + "std": 19.8, + "min": 5, + "max": 130, + "p25": 38.5, + "p75": 54.5, + "p85": 61.0, + "p95": 87.7 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 3.2, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 35 + }, + { + "date": "2022-04-15", + "value": 62 + }, + { + "date": "2022-04-28", + "value": 18 + }, + { + "date": "2022-08-05", + "value": 88 + }, + { + "date": "2022-08-12", + "value": 42 + }, + { + "date": "2022-08-20", + "value": 55 + }, + { + "date": "2022-08-28", + "value": 30 + }, + { + "date": "2023-01-10", + "value": 72 + }, + { + "date": "2023-01-22", + "value": 25 + }, + { + "date": "2023-01-30", + "value": 48 + }, + { + "date": "2023-06-05", + "value": 15 + }, + { + "date": "2023-06-18", + "value": 95 + }, + { + "date": "2023-10-03", + "value": 130 + }, + { + "date": "2023-10-10", + "value": 45 + }, + { + "date": "2023-10-18", + "value": 38 + }, + { + "date": "2023-10-25", + "value": 65 + }, + { + "date": "2023-10-30", + "value": 22 + }, + { + "date": "2024-03-05", + "value": 78 + }, + { + "date": "2024-03-12", + "value": 5 + }, + { + "date": "2024-03-20", + "value": 55 + }, + { + "date": "2024-03-28", + "value": 40 + }, + { + "date": "2024-07-08", + "value": 28 + }, + { + "date": "2024-07-15", + "value": 85 + }, + { + "date": "2024-07-22", + "value": 50 + }, + { + "date": "2024-11-04", + "value": 110 + }, + { + "date": "2024-11-11", + "value": 32 + }, + { + "date": "2024-11-18", + "value": 68 + }, + { + "date": "2024-11-25", + "value": 45 + }, + { + "date": "2024-11-30", + "value": 92 + }, + { + "date": "2025-03-03", + "value": 20 + }, + { + "date": "2025-03-10", + "value": 58 + }, + { + "date": "2025-03-17", + "value": 35 + }, + { + "date": "2025-03-24", + "value": 42 + }, + { + "date": "2025-07-02", + "value": 75 + }, + { + "date": "2025-07-09", + "value": 12 + }, + { + "date": "2025-07-16", + "value": 48 + }, + { + "date": "2025-07-23", + "value": 60 + }, + { + "date": "2025-07-30", + "value": 38 + }, + { + "date": "2025-09-05", + "value": 49 + }, + { + "date": "2025-09-11", + "value": 54 + }, + { + "date": "2025-09-17", + "value": 34 + }, + { + "date": "2025-09-23", + "value": 39 + }, + { + "date": "2025-09-29", + "value": 42 + }, + { + "date": "2025-10-06", + "value": 61 + }, + { + "date": "2025-10-12", + "value": 41 + }, + { + "date": "2025-10-18", + "value": 46 + }, + { + "date": "2025-10-24", + "value": 49 + }, + { + "date": "2025-10-30", + "value": 53 + }, + { + "date": "2025-11-04", + "value": 36 + }, + { + "date": "2025-11-10", + "value": 41 + }, + { + "date": "2025-11-16", + "value": 44 + }, + { + "date": "2025-11-22", + "value": 48 + }, + { + "date": "2025-11-28", + "value": 52 + }, + { + "date": "2025-12-05", + "value": 36 + }, + { + "date": "2025-12-11", + "value": 39 + }, + { + "date": "2025-12-17", + "value": 43 + }, + { + "date": "2025-12-23", + "value": 47 + }, + { + "date": "2025-12-29", + "value": 51 + }, + { + "date": "2026-01-06", + "value": 47 + }, + { + "date": "2026-01-12", + "value": 50 + }, + { + "date": "2026-01-18", + "value": 54 + }, + { + "date": "2026-01-24", + "value": 58 + }, + { + "date": "2026-01-30", + "value": 39 + }, + { + "date": "2026-02-04", + "value": 45 + }, + { + "date": "2026-02-10", + "value": 49 + }, + { + "date": "2026-02-16", + "value": 54 + }, + { + "date": "2026-02-22", + "value": 34 + }, + { + "date": "2026-02-28", + "value": 39 + }, + { + "date": "2026-03-05", + "value": 56 + }, + { + "date": "2026-03-11", + "value": 61 + }, + { + "date": "2026-03-17", + "value": 41 + }, + { + "date": "2026-03-23", + "value": 46 + }, + { + "date": "2026-03-29", + "value": 49 + }, + { + "date": "2026-04-06", + "value": 56 + }, + { + "date": "2026-04-12", + "value": 36 + }, + { + "date": "2026-04-18", + "value": 41 + }, + { + "date": "2026-04-24", + "value": 44 + }, + { + "date": "2026-04-30", + "value": 48 + }, + { + "date": "2026-05-04", + "value": 32 + }, + { + "date": "2026-05-10", + "value": 36 + }, + { + "date": "2026-05-16", + "value": 39 + }, + { + "date": "2026-05-22", + "value": 43 + }, + { + "date": "2026-05-28", + "value": 47 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 38.3, + "median": 35.0, + "p10": 21.4, + "p25": 26.5, + "p75": 48.5, + "p90": 56.6, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 53.8, + "median": 48.5, + "p10": 33.6, + "p25": 39.0, + "p75": 63.3, + "p90": 78.1, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 48.3, + "median": 48.0, + "p10": 29.6, + "p25": 36.5, + "p75": 60.0, + "p90": 67.2, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 55.0, + "median": 55.0, + "p10": 23.0, + "p25": 35.0, + "p75": 75.0, + "p90": 87.0, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 60.0, + "median": 45.0, + "p10": 28.4, + "p25": 38.0, + "p75": 65.0, + "p90": 104.0, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 44.5, + "median": 47.5, + "p10": 15.5, + "p25": 31.3, + "p75": 60.8, + "p90": 71.1, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 54.3, + "median": 50.0, + "p10": 32.4, + "p25": 39.0, + "p75": 67.5, + "p90": 78.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 69.4, + "median": 68.0, + "p10": 37.2, + "p25": 45.0, + "p75": 92.0, + "p90": 102.8, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 38.8, + "median": 38.5, + "p10": 24.5, + "p25": 31.3, + "p75": 46.0, + "p90": 53.2, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 46.6, + "median": 48.0, + "p10": 22.4, + "p25": 38.0, + "p75": 60.0, + "p90": 69.0, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 43.6, + "median": 42.0, + "p10": 36.0, + "p25": 39.0, + "p75": 49.0, + "p90": 52.0, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 50.0, + "median": 49.0, + "p10": 43.0, + "p25": 46.0, + "p75": 53.0, + "p90": 57.8, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 44.2, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 43.2, + "median": 43.0, + "p10": 37.2, + "p25": 39.0, + "p75": 47.0, + "p90": 49.4, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 49.6, + "median": 50.0, + "p10": 42.2, + "p25": 47.0, + "p75": 54.0, + "p90": 56.4, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 44.2, + "median": 45.0, + "p10": 36.0, + "p25": 39.0, + "p75": 49.0, + "p90": 52.0, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 50.6, + "median": 49.0, + "p10": 43.0, + "p25": 46.0, + "p75": 56.0, + "p90": 59.0, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 45.0, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 48.0, + "p90": 52.8, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 39.4, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 43.0, + "p90": 45.4, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 36.6, + "median": 34.0, + "std": 15.8, + "min": 3, + "max": 98, + "p25": 28.0, + "p75": 41.0, + "p85": 45.0, + "p95": 69.2 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 1.8, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 28 + }, + { + "date": "2022-05-10", + "value": 45 + }, + { + "date": "2022-05-18", + "value": 12 + }, + { + "date": "2022-05-25", + "value": 62 + }, + { + "date": "2023-02-06", + "value": 33 + }, + { + "date": "2023-02-14", + "value": 78 + }, + { + "date": "2023-02-22", + "value": 20 + }, + { + "date": "2023-02-28", + "value": 55 + }, + { + "date": "2023-09-05", + "value": 8 + }, + { + "date": "2023-09-15", + "value": 42 + }, + { + "date": "2023-09-25", + "value": 65 + }, + { + "date": "2024-04-03", + "value": 38 + }, + { + "date": "2024-04-10", + "value": 15 + }, + { + "date": "2024-04-17", + "value": 72 + }, + { + "date": "2024-04-24", + "value": 25 + }, + { + "date": "2024-10-02", + "value": 48 + }, + { + "date": "2024-10-09", + "value": 3 + }, + { + "date": "2024-10-16", + "value": 85 + }, + { + "date": "2024-10-23", + "value": 30 + }, + { + "date": "2024-10-30", + "value": 55 + }, + { + "date": "2025-04-07", + "value": 22 + }, + { + "date": "2025-04-14", + "value": 40 + }, + { + "date": "2025-04-21", + "value": 98 + }, + { + "date": "2025-04-28", + "value": 18 + }, + { + "date": "2025-09-04", + "value": 39 + }, + { + "date": "2025-09-10", + "value": 41 + }, + { + "date": "2025-09-16", + "value": 45 + }, + { + "date": "2025-09-22", + "value": 30 + }, + { + "date": "2025-09-28", + "value": 34 + }, + { + "date": "2025-10-05", + "value": 38 + }, + { + "date": "2025-10-11", + "value": 41 + }, + { + "date": "2025-10-17", + "value": 27 + }, + { + "date": "2025-10-23", + "value": 30 + }, + { + "date": "2025-10-29", + "value": 32 + }, + { + "date": "2025-11-06", + "value": 38 + }, + { + "date": "2025-11-12", + "value": 23 + }, + { + "date": "2025-11-18", + "value": 27 + }, + { + "date": "2025-11-24", + "value": 29 + }, + { + "date": "2025-11-30", + "value": 32 + }, + { + "date": "2025-12-04", + "value": 28 + }, + { + "date": "2025-12-10", + "value": 32 + }, + { + "date": "2025-12-16", + "value": 34 + }, + { + "date": "2025-12-22", + "value": 37 + }, + { + "date": "2025-12-28", + "value": 40 + }, + { + "date": "2026-01-05", + "value": 28 + }, + { + "date": "2026-01-11", + "value": 31 + }, + { + "date": "2026-01-17", + "value": 33 + }, + { + "date": "2026-01-23", + "value": 36 + }, + { + "date": "2026-01-29", + "value": 39 + }, + { + "date": "2026-02-06", + "value": 36 + }, + { + "date": "2026-02-12", + "value": 39 + }, + { + "date": "2026-02-18", + "value": 41 + }, + { + "date": "2026-02-24", + "value": 45 + }, + { + "date": "2026-02-30", + "value": 30 + }, + { + "date": "2026-03-04", + "value": 35 + }, + { + "date": "2026-03-10", + "value": 38 + }, + { + "date": "2026-03-16", + "value": 41 + }, + { + "date": "2026-03-22", + "value": 27 + }, + { + "date": "2026-03-28", + "value": 30 + }, + { + "date": "2026-04-05", + "value": 34 + }, + { + "date": "2026-04-11", + "value": 38 + }, + { + "date": "2026-04-17", + "value": 23 + }, + { + "date": "2026-04-23", + "value": 27 + }, + { + "date": "2026-04-29", + "value": 29 + }, + { + "date": "2026-05-06", + "value": 43 + }, + { + "date": "2026-05-12", + "value": 28 + }, + { + "date": "2026-05-18", + "value": 32 + }, + { + "date": "2026-05-24", + "value": 34 + }, + { + "date": "2026-05-30", + "value": 37 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 36.8, + "median": 36.5, + "p10": 16.8, + "p25": 24.0, + "p75": 49.3, + "p90": 56.9, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 46.5, + "median": 44.0, + "p10": 23.9, + "p25": 29.8, + "p75": 60.8, + "p90": 71.1, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 38.3, + "median": 42.0, + "p10": 14.8, + "p25": 25.0, + "p75": 53.5, + "p90": 60.4, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 37.5, + "median": 31.5, + "p10": 18.0, + "p25": 22.5, + "p75": 46.5, + "p90": 61.8, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 44.2, + "median": 48.0, + "p10": 13.8, + "p25": 30.0, + "p75": 55.0, + "p90": 73.0, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 44.5, + "median": 31.0, + "p10": 19.2, + "p25": 21.0, + "p75": 54.5, + "p90": 80.6, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 37.8, + "median": 39.0, + "p10": 31.6, + "p25": 34.0, + "p75": 41.0, + "p90": 43.4, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 33.6, + "median": 32.0, + "p10": 28.2, + "p25": 30.0, + "p75": 38.0, + "p90": 39.8, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 29.8, + "median": 29.0, + "p10": 24.6, + "p25": 27.0, + "p75": 32.0, + "p90": 35.6, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 34.2, + "median": 34.0, + "p10": 29.6, + "p25": 32.0, + "p75": 37.0, + "p90": 38.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 33.4, + "median": 33.0, + "p10": 29.2, + "p25": 31.0, + "p75": 36.0, + "p90": 37.8, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 38.2, + "median": 39.0, + "p10": 32.4, + "p25": 36.0, + "p75": 41.0, + "p90": 43.4, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 34.2, + "median": 35.0, + "p10": 28.2, + "p25": 30.0, + "p75": 38.0, + "p90": 39.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 30.2, + "median": 29.0, + "p10": 24.6, + "p25": 27.0, + "p75": 34.0, + "p90": 36.4, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 34.8, + "median": 34.0, + "p10": 29.6, + "p25": 32.0, + "p75": 37.0, + "p90": 40.6, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 43.9, + "median": 41.0, + "std": 19.1, + "min": 4, + "max": 115, + "p25": 34.3, + "p75": 50.0, + "p85": 54.0, + "p95": 81.9 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 5.5, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 40 + }, + { + "date": "2022-06-15", + "value": 22 + }, + { + "date": "2022-06-25", + "value": 68 + }, + { + "date": "2023-03-08", + "value": 4 + }, + { + "date": "2023-03-15", + "value": 55 + }, + { + "date": "2023-03-22", + "value": 115 + }, + { + "date": "2023-03-29", + "value": 30 + }, + { + "date": "2023-11-06", + "value": 62 + }, + { + "date": "2023-11-13", + "value": 18 + }, + { + "date": "2023-11-20", + "value": 85 + }, + { + "date": "2024-06-03", + "value": 35 + }, + { + "date": "2024-06-10", + "value": 72 + }, + { + "date": "2024-06-17", + "value": 10 + }, + { + "date": "2024-06-24", + "value": 48 + }, + { + "date": "2024-06-30", + "value": 95 + }, + { + "date": "2025-01-07", + "value": 28 + }, + { + "date": "2025-01-14", + "value": 52 + }, + { + "date": "2025-01-21", + "value": 15 + }, + { + "date": "2025-01-28", + "value": 78 + }, + { + "date": "2025-08-04", + "value": 42 + }, + { + "date": "2025-08-08", + "value": 8 + }, + { + "date": "2025-08-12", + "value": 65 + }, + { + "date": "2025-08-16", + "value": 33 + }, + { + "date": "2025-08-20", + "value": 100 + }, + { + "date": "2025-08-24", + "value": 20 + }, + { + "date": "2025-09-06", + "value": 41 + }, + { + "date": "2025-09-12", + "value": 45 + }, + { + "date": "2025-09-18", + "value": 48 + }, + { + "date": "2025-09-24", + "value": 52 + }, + { + "date": "2025-09-30", + "value": 34 + }, + { + "date": "2025-10-04", + "value": 40 + }, + { + "date": "2025-10-10", + "value": 44 + }, + { + "date": "2025-10-16", + "value": 48 + }, + { + "date": "2025-10-22", + "value": 30 + }, + { + "date": "2025-10-28", + "value": 34 + }, + { + "date": "2025-11-05", + "value": 50 + }, + { + "date": "2025-11-11", + "value": 54 + }, + { + "date": "2025-11-17", + "value": 36 + }, + { + "date": "2025-11-23", + "value": 41 + }, + { + "date": "2025-11-29", + "value": 44 + }, + { + "date": "2025-12-06", + "value": 50 + }, + { + "date": "2025-12-12", + "value": 32 + }, + { + "date": "2025-12-18", + "value": 36 + }, + { + "date": "2025-12-24", + "value": 39 + }, + { + "date": "2025-12-30", + "value": 43 + }, + { + "date": "2026-01-04", + "value": 28 + }, + { + "date": "2026-01-10", + "value": 32 + }, + { + "date": "2026-01-16", + "value": 35 + }, + { + "date": "2026-01-22", + "value": 38 + }, + { + "date": "2026-01-28", + "value": 42 + }, + { + "date": "2026-02-05", + "value": 39 + }, + { + "date": "2026-02-11", + "value": 41 + }, + { + "date": "2026-02-17", + "value": 45 + }, + { + "date": "2026-02-23", + "value": 48 + }, + { + "date": "2026-02-29", + "value": 52 + }, + { + "date": "2026-03-06", + "value": 37 + }, + { + "date": "2026-03-12", + "value": 40 + }, + { + "date": "2026-03-18", + "value": 44 + }, + { + "date": "2026-03-24", + "value": 48 + }, + { + "date": "2026-03-30", + "value": 30 + }, + { + "date": "2026-04-04", + "value": 47 + }, + { + "date": "2026-04-10", + "value": 50 + }, + { + "date": "2026-04-16", + "value": 54 + }, + { + "date": "2026-04-22", + "value": 36 + }, + { + "date": "2026-04-28", + "value": 41 + }, + { + "date": "2026-05-05", + "value": 46 + }, + { + "date": "2026-05-11", + "value": 50 + }, + { + "date": "2026-05-17", + "value": 32 + }, + { + "date": "2026-05-23", + "value": 36 + }, + { + "date": "2026-05-29", + "value": 39 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 43.3, + "median": 40.0, + "p10": 25.6, + "p25": 31.0, + "p75": 54.0, + "p90": 62.4, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 51.0, + "median": 42.5, + "p10": 11.8, + "p25": 23.5, + "p75": 70.0, + "p90": 97.0, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 55.0, + "median": 62.0, + "p10": 26.8, + "p25": 40.0, + "p75": 73.5, + "p90": 80.4, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 52.0, + "median": 48.0, + "p10": 20.0, + "p25": 35.0, + "p75": 72.0, + "p90": 85.8, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 43.3, + "median": 40.0, + "p10": 18.9, + "p25": 24.8, + "p75": 58.5, + "p90": 70.2, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 44.7, + "median": 37.5, + "p10": 14.0, + "p25": 23.3, + "p75": 59.3, + "p90": 82.5, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 44.0, + "median": 45.0, + "p10": 36.8, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 39.2, + "median": 40.0, + "p10": 31.6, + "p25": 34.0, + "p75": 44.0, + "p90": 46.4, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 45.0, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 40.0, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 43.0, + "p90": 47.2, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 35.0, + "median": 35.0, + "p10": 29.6, + "p25": 32.0, + "p75": 38.0, + "p90": 40.4, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 45.0, + "median": 45.0, + "p10": 39.8, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 39.8, + "median": 40.0, + "p10": 32.8, + "p25": 37.0, + "p75": 44.0, + "p90": 46.4, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 45.6, + "median": 47.0, + "p10": 38.0, + "p25": 41.0, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 40.6, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 46.0, + "p90": 48.4, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 4.4, + "median": 4.0, + "std": 1.8, + "min": 1, + "max": 14, + "p25": 3.3, + "p75": 5.0, + "p85": 5.0, + "p95": 6.6 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 3 + }, + { + "date": "2022-07-05", + "value": 5 + }, + { + "date": "2022-10-12", + "value": 2 + }, + { + "date": "2023-01-20", + "value": 7 + }, + { + "date": "2023-04-15", + "value": 4 + }, + { + "date": "2023-07-28", + "value": 6 + }, + { + "date": "2023-10-05", + "value": 3 + }, + { + "date": "2024-01-12", + "value": 14 + }, + { + "date": "2024-04-22", + "value": 4 + }, + { + "date": "2024-07-10", + "value": 8 + }, + { + "date": "2024-10-18", + "value": 3 + }, + { + "date": "2025-01-25", + "value": 5 + }, + { + "date": "2025-05-08", + "value": 1 + }, + { + "date": "2025-08-15", + "value": 6 + }, + { + "date": "2025-09-04", + "value": 3 + }, + { + "date": "2025-09-10", + "value": 4 + }, + { + "date": "2025-09-16", + "value": 4 + }, + { + "date": "2025-09-22", + "value": 4 + }, + { + "date": "2025-10-05", + "value": 3 + }, + { + "date": "2025-10-11", + "value": 4 + }, + { + "date": "2025-10-17", + "value": 4 + }, + { + "date": "2025-10-23", + "value": 4 + }, + { + "date": "2025-11-06", + "value": 4 + }, + { + "date": "2025-11-12", + "value": 5 + }, + { + "date": "2025-11-18", + "value": 5 + }, + { + "date": "2025-11-24", + "value": 5 + }, + { + "date": "2025-12-04", + "value": 4 + }, + { + "date": "2025-12-10", + "value": 5 + }, + { + "date": "2025-12-16", + "value": 5 + }, + { + "date": "2025-12-22", + "value": 3 + }, + { + "date": "2026-01-05", + "value": 4 + }, + { + "date": "2026-01-11", + "value": 5 + }, + { + "date": "2026-01-17", + "value": 3 + }, + { + "date": "2026-01-23", + "value": 3 + }, + { + "date": "2026-02-06", + "value": 5 + }, + { + "date": "2026-02-12", + "value": 3 + }, + { + "date": "2026-02-18", + "value": 4 + }, + { + "date": "2026-02-24", + "value": 4 + }, + { + "date": "2026-03-04", + "value": 3 + }, + { + "date": "2026-03-10", + "value": 3 + }, + { + "date": "2026-03-16", + "value": 4 + }, + { + "date": "2026-03-22", + "value": 4 + }, + { + "date": "2026-04-05", + "value": 4 + }, + { + "date": "2026-04-11", + "value": 4 + }, + { + "date": "2026-04-17", + "value": 5 + }, + { + "date": "2026-04-23", + "value": 5 + }, + { + "date": "2026-05-06", + "value": 4 + }, + { + "date": "2026-05-12", + "value": 4 + }, + { + "date": "2026-05-18", + "value": 5 + }, + { + "date": "2026-05-24", + "value": 5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 14.0, + "median": 14.0, + "p10": 14.0, + "p25": 14.0, + "p75": 14.0, + "p90": 14.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 4.8, + "median": 5.0, + "p10": 4.3, + "p25": 4.8, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 4.3, + "median": 4.5, + "p10": 3.3, + "p25": 3.8, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.8, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.3, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.0, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.3, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 4.5, + "median": 4.5, + "p10": 4.0, + "p25": 4.0, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.5, + "median": 4.5, + "p10": 4.0, + "p25": 4.0, + "p75": 5.0, + "p90": 5.0, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 17.4, + "median": 16.0, + "std": 9.0, + "min": 2, + "max": 55, + "p25": 13.0, + "p75": 19.0, + "p85": 20.4, + "p95": 37.0 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 12.5, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 12 + }, + { + "date": "2022-05-15", + "value": 25 + }, + { + "date": "2022-05-22", + "value": 8 + }, + { + "date": "2022-11-03", + "value": 35 + }, + { + "date": "2022-11-10", + "value": 15 + }, + { + "date": "2022-11-18", + "value": 5 + }, + { + "date": "2022-11-25", + "value": 22 + }, + { + "date": "2023-05-08", + "value": 18 + }, + { + "date": "2023-05-15", + "value": 40 + }, + { + "date": "2023-05-22", + "value": 10 + }, + { + "date": "2023-11-06", + "value": 55 + }, + { + "date": "2023-11-13", + "value": 2 + }, + { + "date": "2023-11-20", + "value": 28 + }, + { + "date": "2023-11-27", + "value": 15 + }, + { + "date": "2023-11-30", + "value": 8 + }, + { + "date": "2024-05-06", + "value": 20 + }, + { + "date": "2024-05-13", + "value": 45 + }, + { + "date": "2024-05-20", + "value": 12 + }, + { + "date": "2024-05-27", + "value": 3 + }, + { + "date": "2024-11-04", + "value": 18 + }, + { + "date": "2024-11-11", + "value": 30 + }, + { + "date": "2024-11-18", + "value": 8 + }, + { + "date": "2025-05-05", + "value": 22 + }, + { + "date": "2025-05-09", + "value": 35 + }, + { + "date": "2025-05-13", + "value": 5 + }, + { + "date": "2025-05-17", + "value": 15 + }, + { + "date": "2025-05-21", + "value": 42 + }, + { + "date": "2025-05-25", + "value": 10 + }, + { + "date": "2025-09-05", + "value": 14 + }, + { + "date": "2025-09-11", + "value": 16 + }, + { + "date": "2025-09-17", + "value": 17 + }, + { + "date": "2025-09-23", + "value": 18 + }, + { + "date": "2025-09-29", + "value": 19 + }, + { + "date": "2025-10-06", + "value": 14 + }, + { + "date": "2025-10-12", + "value": 15 + }, + { + "date": "2025-10-18", + "value": 16 + }, + { + "date": "2025-10-24", + "value": 18 + }, + { + "date": "2025-10-30", + "value": 11 + }, + { + "date": "2025-11-04", + "value": 18 + }, + { + "date": "2025-11-10", + "value": 19 + }, + { + "date": "2025-11-16", + "value": 20 + }, + { + "date": "2025-11-22", + "value": 14 + }, + { + "date": "2025-11-28", + "value": 15 + }, + { + "date": "2025-12-05", + "value": 17 + }, + { + "date": "2025-12-11", + "value": 19 + }, + { + "date": "2025-12-17", + "value": 12 + }, + { + "date": "2025-12-23", + "value": 14 + }, + { + "date": "2025-12-29", + "value": 15 + }, + { + "date": "2026-01-06", + "value": 17 + }, + { + "date": "2026-01-12", + "value": 11 + }, + { + "date": "2026-01-18", + "value": 12 + }, + { + "date": "2026-01-24", + "value": 13 + }, + { + "date": "2026-01-30", + "value": 14 + }, + { + "date": "2026-02-04", + "value": 13 + }, + { + "date": "2026-02-10", + "value": 14 + }, + { + "date": "2026-02-16", + "value": 16 + }, + { + "date": "2026-02-22", + "value": 17 + }, + { + "date": "2026-02-28", + "value": 18 + }, + { + "date": "2026-03-05", + "value": 13 + }, + { + "date": "2026-03-11", + "value": 14 + }, + { + "date": "2026-03-17", + "value": 15 + }, + { + "date": "2026-03-23", + "value": 16 + }, + { + "date": "2026-03-29", + "value": 18 + }, + { + "date": "2026-04-06", + "value": 16 + }, + { + "date": "2026-04-12", + "value": 18 + }, + { + "date": "2026-04-18", + "value": 19 + }, + { + "date": "2026-04-24", + "value": 20 + }, + { + "date": "2026-04-30", + "value": 14 + }, + { + "date": "2026-05-04", + "value": 16 + }, + { + "date": "2026-05-10", + "value": 17 + }, + { + "date": "2026-05-16", + "value": 19 + }, + { + "date": "2026-05-22", + "value": 12 + }, + { + "date": "2026-05-28", + "value": 14 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 15.0, + "median": 12.0, + "p10": 8.8, + "p25": 10.0, + "p75": 18.5, + "p90": 22.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 19.3, + "median": 18.5, + "p10": 8.0, + "p25": 12.5, + "p75": 25.3, + "p90": 31.1, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 22.7, + "median": 18.0, + "p10": 11.6, + "p25": 14.0, + "p75": 29.0, + "p90": 35.6, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 21.6, + "median": 15.0, + "p10": 4.4, + "p25": 8.0, + "p75": 28.0, + "p90": 44.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 20.0, + "median": 16.0, + "p10": 5.7, + "p25": 9.8, + "p75": 26.3, + "p90": 37.5, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 18.7, + "median": 18.0, + "p10": 10.0, + "p25": 13.0, + "p75": 24.0, + "p90": 27.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 21.5, + "median": 18.5, + "p10": 7.5, + "p25": 11.3, + "p75": 31.8, + "p90": 38.5, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 16.8, + "median": 17.0, + "p10": 14.8, + "p25": 16.0, + "p75": 18.0, + "p90": 18.6, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 14.8, + "median": 15.0, + "p10": 12.2, + "p25": 14.0, + "p75": 16.0, + "p90": 17.2, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 17.2, + "median": 18.0, + "p10": 14.4, + "p25": 15.0, + "p75": 19.0, + "p90": 19.6, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 15.4, + "median": 15.0, + "p10": 12.8, + "p25": 14.0, + "p75": 17.0, + "p90": 18.2, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 13.4, + "median": 13.0, + "p10": 11.4, + "p25": 12.0, + "p75": 14.0, + "p90": 15.8, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 15.6, + "median": 16.0, + "p10": 13.4, + "p25": 14.0, + "p75": 17.0, + "p90": 17.6, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 15.2, + "median": 15.0, + "p10": 13.4, + "p25": 14.0, + "p75": 16.0, + "p90": 17.2, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 17.4, + "median": 18.0, + "p10": 14.8, + "p25": 16.0, + "p75": 19.0, + "p90": 19.6, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 15.6, + "median": 16.0, + "p10": 12.8, + "p25": 14.0, + "p75": 17.0, + "p90": 18.2, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 3.2, + "median": 3.0, + "std": 1.4, + "min": 0, + "max": 10, + "p25": 3.0, + "p75": 4.0, + "p85": 4.0, + "p95": 5.2 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 2 + }, + { + "date": "2022-06-10", + "value": 3 + }, + { + "date": "2022-07-15", + "value": 1 + }, + { + "date": "2022-08-22", + "value": 4 + }, + { + "date": "2022-10-05", + "value": 2 + }, + { + "date": "2022-11-18", + "value": 5 + }, + { + "date": "2023-01-10", + "value": 3 + }, + { + "date": "2023-03-25", + "value": 7 + }, + { + "date": "2023-05-12", + "value": 2 + }, + { + "date": "2023-07-08", + "value": 4 + }, + { + "date": "2023-09-15", + "value": 1 + }, + { + "date": "2023-11-22", + "value": 3 + }, + { + "date": "2024-01-18", + "value": 10 + }, + { + "date": "2024-03-08", + "value": 3 + }, + { + "date": "2024-05-15", + "value": 2 + }, + { + "date": "2024-07-22", + "value": 5 + }, + { + "date": "2024-09-10", + "value": 0 + }, + { + "date": "2024-11-05", + "value": 4 + }, + { + "date": "2025-01-15", + "value": 3 + }, + { + "date": "2025-03-20", + "value": 2 + }, + { + "date": "2025-05-28", + "value": 6 + }, + { + "date": "2025-08-05", + "value": 3 + }, + { + "date": "2025-09-05", + "value": 4 + }, + { + "date": "2025-09-11", + "value": 4 + }, + { + "date": "2025-09-17", + "value": 3 + }, + { + "date": "2025-09-23", + "value": 3 + }, + { + "date": "2025-10-06", + "value": 4 + }, + { + "date": "2025-10-12", + "value": 2 + }, + { + "date": "2025-10-18", + "value": 3 + }, + { + "date": "2025-10-24", + "value": 3 + }, + { + "date": "2025-11-04", + "value": 2 + }, + { + "date": "2025-11-10", + "value": 2 + }, + { + "date": "2025-11-16", + "value": 3 + }, + { + "date": "2025-11-22", + "value": 3 + }, + { + "date": "2025-12-05", + "value": 3 + }, + { + "date": "2025-12-11", + "value": 3 + }, + { + "date": "2025-12-17", + "value": 3 + }, + { + "date": "2025-12-23", + "value": 4 + }, + { + "date": "2026-01-06", + "value": 3 + }, + { + "date": "2026-01-12", + "value": 3 + }, + { + "date": "2026-01-18", + "value": 3 + }, + { + "date": "2026-01-24", + "value": 4 + }, + { + "date": "2026-02-04", + "value": 4 + }, + { + "date": "2026-02-10", + "value": 4 + }, + { + "date": "2026-02-16", + "value": 4 + }, + { + "date": "2026-02-22", + "value": 3 + }, + { + "date": "2026-03-05", + "value": 3 + }, + { + "date": "2026-03-11", + "value": 4 + }, + { + "date": "2026-03-17", + "value": 2 + }, + { + "date": "2026-03-23", + "value": 3 + }, + { + "date": "2026-04-06", + "value": 3 + }, + { + "date": "2026-04-12", + "value": 2 + }, + { + "date": "2026-04-18", + "value": 2 + }, + { + "date": "2026-04-24", + "value": 3 + }, + { + "date": "2026-05-04", + "value": 3 + }, + { + "date": "2026-05-10", + "value": 3 + }, + { + "date": "2026-05-16", + "value": 3 + }, + { + "date": "2026-05-22", + "value": 3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2022-08", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.0, + "p25": 2.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.0, + "p25": 2.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 3.4, + "median": 3.0, + "std": 1.8, + "min": 0, + "max": 13, + "p25": 3.0, + "p75": 4.0, + "p85": 4.0, + "p95": 6.2 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 2 + }, + { + "date": "2022-06-13", + "value": 1 + }, + { + "date": "2022-07-16", + "value": 3 + }, + { + "date": "2022-08-26", + "value": 2 + }, + { + "date": "2022-10-07", + "value": 5 + }, + { + "date": "2022-11-23", + "value": 2 + }, + { + "date": "2023-01-13", + "value": 4 + }, + { + "date": "2023-04-01", + "value": 3 + }, + { + "date": "2023-05-14", + "value": 6 + }, + { + "date": "2023-07-12", + "value": 2 + }, + { + "date": "2023-09-16", + "value": 13 + }, + { + "date": "2023-11-25", + "value": 3 + }, + { + "date": "2024-01-28", + "value": 7 + }, + { + "date": "2024-03-11", + "value": 1 + }, + { + "date": "2024-05-17", + "value": 4 + }, + { + "date": "2024-07-27", + "value": 5 + }, + { + "date": "2024-09-10", + "value": 2 + }, + { + "date": "2024-11-09", + "value": 0 + }, + { + "date": "2025-01-18", + "value": 3 + }, + { + "date": "2025-03-22", + "value": 8 + }, + { + "date": "2025-06-03", + "value": 2 + }, + { + "date": "2025-08-08", + "value": 5 + }, + { + "date": "2025-09-04", + "value": 2 + }, + { + "date": "2025-09-10", + "value": 3 + }, + { + "date": "2025-09-16", + "value": 3 + }, + { + "date": "2025-09-22", + "value": 3 + }, + { + "date": "2025-10-05", + "value": 3 + }, + { + "date": "2025-10-11", + "value": 3 + }, + { + "date": "2025-10-17", + "value": 4 + }, + { + "date": "2025-10-23", + "value": 4 + }, + { + "date": "2025-11-06", + "value": 3 + }, + { + "date": "2025-11-12", + "value": 3 + }, + { + "date": "2025-11-18", + "value": 3 + }, + { + "date": "2025-11-24", + "value": 4 + }, + { + "date": "2025-12-04", + "value": 3 + }, + { + "date": "2025-12-10", + "value": 3 + }, + { + "date": "2025-12-16", + "value": 3 + }, + { + "date": "2025-12-22", + "value": 2 + }, + { + "date": "2026-01-05", + "value": 4 + }, + { + "date": "2026-01-11", + "value": 4 + }, + { + "date": "2026-01-17", + "value": 3 + }, + { + "date": "2026-01-23", + "value": 3 + }, + { + "date": "2026-02-06", + "value": 4 + }, + { + "date": "2026-02-12", + "value": 2 + }, + { + "date": "2026-02-18", + "value": 3 + }, + { + "date": "2026-02-24", + "value": 3 + }, + { + "date": "2026-03-04", + "value": 3 + }, + { + "date": "2026-03-10", + "value": 3 + }, + { + "date": "2026-03-16", + "value": 3 + }, + { + "date": "2026-03-22", + "value": 4 + }, + { + "date": "2026-04-05", + "value": 3 + }, + { + "date": "2026-04-11", + "value": 3 + }, + { + "date": "2026-04-17", + "value": 3 + }, + { + "date": "2026-04-23", + "value": 3 + }, + { + "date": "2026-05-06", + "value": 3 + }, + { + "date": "2026-05-12", + "value": 3 + }, + { + "date": "2026-05-18", + "value": 3 + }, + { + "date": "2026-05-24", + "value": 3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 13.0, + "median": 13.0, + "p10": 13.0, + "p25": 13.0, + "p75": 13.0, + "p90": 13.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.8, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.8, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 12.7, + "median": 12.0, + "std": 5.6, + "min": 2, + "max": 42, + "p25": 10.0, + "p75": 14.0, + "p85": 15.0, + "p95": 20.4 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 28.5, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 8 + }, + { + "date": "2023-03-25", + "value": 22 + }, + { + "date": "2023-09-20", + "value": 42 + }, + { + "date": "2024-03-15", + "value": 6 + }, + { + "date": "2024-03-28", + "value": 18 + }, + { + "date": "2024-09-05", + "value": 28 + }, + { + "date": "2024-09-15", + "value": 12 + }, + { + "date": "2024-09-25", + "value": 2 + }, + { + "date": "2025-03-10", + "value": 15 + }, + { + "date": "2025-03-22", + "value": 5 + }, + { + "date": "2025-07-08", + "value": 20 + }, + { + "date": "2025-07-22", + "value": 4 + }, + { + "date": "2025-09-05", + "value": 14 + }, + { + "date": "2025-09-11", + "value": 15 + }, + { + "date": "2025-09-17", + "value": 10 + }, + { + "date": "2025-09-23", + "value": 11 + }, + { + "date": "2025-09-29", + "value": 12 + }, + { + "date": "2025-10-06", + "value": 14 + }, + { + "date": "2025-10-12", + "value": 8 + }, + { + "date": "2025-10-18", + "value": 10 + }, + { + "date": "2025-10-24", + "value": 11 + }, + { + "date": "2025-10-30", + "value": 11 + }, + { + "date": "2025-11-04", + "value": 10 + }, + { + "date": "2025-11-10", + "value": 12 + }, + { + "date": "2025-11-16", + "value": 12 + }, + { + "date": "2025-11-22", + "value": 13 + }, + { + "date": "2025-11-28", + "value": 14 + }, + { + "date": "2025-12-05", + "value": 10 + }, + { + "date": "2025-12-11", + "value": 11 + }, + { + "date": "2025-12-17", + "value": 12 + }, + { + "date": "2025-12-23", + "value": 13 + }, + { + "date": "2025-12-29", + "value": 14 + }, + { + "date": "2026-01-06", + "value": 13 + }, + { + "date": "2026-01-12", + "value": 14 + }, + { + "date": "2026-01-18", + "value": 15 + }, + { + "date": "2026-01-24", + "value": 16 + }, + { + "date": "2026-01-30", + "value": 11 + }, + { + "date": "2026-02-04", + "value": 13 + }, + { + "date": "2026-02-10", + "value": 14 + }, + { + "date": "2026-02-16", + "value": 15 + }, + { + "date": "2026-02-22", + "value": 10 + }, + { + "date": "2026-02-28", + "value": 11 + }, + { + "date": "2026-03-05", + "value": 13 + }, + { + "date": "2026-03-11", + "value": 14 + }, + { + "date": "2026-03-17", + "value": 8 + }, + { + "date": "2026-03-23", + "value": 10 + }, + { + "date": "2026-03-29", + "value": 11 + }, + { + "date": "2026-04-06", + "value": 16 + }, + { + "date": "2026-04-12", + "value": 10 + }, + { + "date": "2026-04-18", + "value": 12 + }, + { + "date": "2026-04-24", + "value": 12 + }, + { + "date": "2026-04-30", + "value": 13 + }, + { + "date": "2026-05-04", + "value": 9 + }, + { + "date": "2026-05-10", + "value": 10 + }, + { + "date": "2026-05-16", + "value": 11 + }, + { + "date": "2026-05-22", + "value": 12 + }, + { + "date": "2026-05-28", + "value": 13 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 15.0, + "median": 15.0, + "p10": 9.4, + "p25": 11.5, + "p75": 18.5, + "p90": 20.6, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 12.0, + "median": 12.0, + "p10": 7.2, + "p25": 9.0, + "p75": 15.0, + "p90": 16.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 14.0, + "median": 12.0, + "p10": 4.0, + "p25": 7.0, + "p75": 20.0, + "p90": 24.8, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 10.0, + "median": 10.0, + "p10": 6.0, + "p25": 7.5, + "p75": 12.5, + "p90": 14.0, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 12.0, + "median": 12.0, + "p10": 5.6, + "p25": 8.0, + "p75": 16.0, + "p90": 18.4, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 12.4, + "median": 12.0, + "p10": 10.4, + "p25": 11.0, + "p75": 14.0, + "p90": 14.6, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 10.8, + "median": 11.0, + "p10": 8.8, + "p25": 10.0, + "p75": 11.0, + "p90": 12.8, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 12.2, + "median": 12.0, + "p10": 10.8, + "p25": 12.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 12.0, + "median": 12.0, + "p10": 10.4, + "p25": 11.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 13.8, + "median": 14.0, + "p10": 11.8, + "p25": 13.0, + "p75": 15.0, + "p90": 15.6, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 12.6, + "median": 13.0, + "p10": 10.4, + "p25": 11.0, + "p75": 14.0, + "p90": 14.6, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 11.2, + "median": 11.0, + "p10": 8.8, + "p25": 10.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 12.6, + "median": 12.0, + "p10": 10.8, + "p25": 12.0, + "p75": 13.0, + "p90": 14.8, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 11.0, + "median": 11.0, + "p10": 9.4, + "p25": 10.0, + "p75": 12.0, + "p90": 12.6, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 20.9, + "median": 21.0, + "std": 4.6, + "min": 12, + "max": 38, + "p25": 18.5, + "p75": 23.0, + "p85": 24.9, + "p95": 26.6 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 18 + }, + { + "date": "2023-10-12", + "value": 25 + }, + { + "date": "2024-04-08", + "value": 12 + }, + { + "date": "2024-09-20", + "value": 38 + }, + { + "date": "2024-10-15", + "value": 20 + }, + { + "date": "2025-03-25", + "value": 15 + }, + { + "date": "2025-04-10", + "value": 28 + }, + { + "date": "2025-07-30", + "value": 24 + }, + { + "date": "2025-09-04", + "value": 17 + }, + { + "date": "2025-09-10", + "value": 19 + }, + { + "date": "2025-09-16", + "value": 21 + }, + { + "date": "2025-10-05", + "value": 17 + }, + { + "date": "2025-10-11", + "value": 19 + }, + { + "date": "2025-10-17", + "value": 20 + }, + { + "date": "2025-11-06", + "value": 22 + }, + { + "date": "2025-11-12", + "value": 23 + }, + { + "date": "2025-11-18", + "value": 25 + }, + { + "date": "2025-12-04", + "value": 21 + }, + { + "date": "2025-12-10", + "value": 23 + }, + { + "date": "2025-12-16", + "value": 25 + }, + { + "date": "2026-01-05", + "value": 21 + }, + { + "date": "2026-01-11", + "value": 23 + }, + { + "date": "2026-01-17", + "value": 14 + }, + { + "date": "2026-02-06", + "value": 26 + }, + { + "date": "2026-02-12", + "value": 17 + }, + { + "date": "2026-02-18", + "value": 19 + }, + { + "date": "2026-03-04", + "value": 15 + }, + { + "date": "2026-03-10", + "value": 17 + }, + { + "date": "2026-03-16", + "value": 19 + }, + { + "date": "2026-04-05", + "value": 20 + }, + { + "date": "2026-04-11", + "value": 22 + }, + { + "date": "2026-04-17", + "value": 23 + }, + { + "date": "2026-05-06", + "value": 20 + }, + { + "date": "2026-05-12", + "value": 21 + }, + { + "date": "2026-05-18", + "value": 23 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 20.0, + "median": 20.0, + "p10": 20.0, + "p25": 20.0, + "p75": 20.0, + "p90": 20.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 24.0, + "median": 24.0, + "p10": 24.0, + "p25": 24.0, + "p75": 24.0, + "p90": 24.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 19.0, + "median": 19.0, + "p10": 17.4, + "p25": 18.0, + "p75": 20.0, + "p90": 20.6, + "n": 3 + }, + { + "month": "2025-10", + "mean": 18.7, + "median": 19.0, + "p10": 17.4, + "p25": 18.0, + "p75": 19.5, + "p90": 19.8, + "n": 3 + }, + { + "month": "2025-11", + "mean": 23.3, + "median": 23.0, + "p10": 22.2, + "p25": 22.5, + "p75": 24.0, + "p90": 24.6, + "n": 3 + }, + { + "month": "2025-12", + "mean": 23.0, + "median": 23.0, + "p10": 21.4, + "p25": 22.0, + "p75": 24.0, + "p90": 24.6, + "n": 3 + }, + { + "month": "2026-01", + "mean": 19.3, + "median": 21.0, + "p10": 15.4, + "p25": 17.5, + "p75": 22.0, + "p90": 22.6, + "n": 3 + }, + { + "month": "2026-02", + "mean": 20.7, + "median": 19.0, + "p10": 17.4, + "p25": 18.0, + "p75": 22.5, + "p90": 24.6, + "n": 3 + }, + { + "month": "2026-03", + "mean": 17.0, + "median": 17.0, + "p10": 15.4, + "p25": 16.0, + "p75": 18.0, + "p90": 18.6, + "n": 3 + }, + { + "month": "2026-04", + "mean": 21.7, + "median": 22.0, + "p10": 20.4, + "p25": 21.0, + "p75": 22.5, + "p90": 22.8, + "n": 3 + }, + { + "month": "2026-05", + "mean": 21.3, + "median": 21.0, + "p10": 20.2, + "p25": 20.5, + "p75": 22.0, + "p90": 22.6, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 31.3, + "median": 30.5, + "std": 7.1, + "min": 15, + "max": 55, + "p25": 27.0, + "p75": 36.0, + "p85": 38.0, + "p95": 41.9 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 28 + }, + { + "date": "2022-11-30", + "value": 35 + }, + { + "date": "2023-03-15", + "value": 22 + }, + { + "date": "2023-07-10", + "value": 42 + }, + { + "date": "2023-10-25", + "value": 30 + }, + { + "date": "2024-02-08", + "value": 55 + }, + { + "date": "2024-05-20", + "value": 25 + }, + { + "date": "2024-08-12", + "value": 38 + }, + { + "date": "2024-11-05", + "value": 15 + }, + { + "date": "2025-01-22", + "value": 32 + }, + { + "date": "2025-04-10", + "value": 28 + }, + { + "date": "2025-06-18", + "value": 45 + }, + { + "date": "2025-07-15", + "value": 30 + }, + { + "date": "2025-08-05", + "value": 22 + }, + { + "date": "2025-09-05", + "value": 36 + }, + { + "date": "2025-09-10", + "value": 38 + }, + { + "date": "2025-09-11", + "value": 39 + }, + { + "date": "2025-09-17", + "value": 26 + }, + { + "date": "2025-10-06", + "value": 36 + }, + { + "date": "2025-10-12", + "value": 23 + }, + { + "date": "2025-10-18", + "value": 26 + }, + { + "date": "2025-11-04", + "value": 27 + }, + { + "date": "2025-11-10", + "value": 31 + }, + { + "date": "2025-11-16", + "value": 33 + }, + { + "date": "2025-12-05", + "value": 27 + }, + { + "date": "2025-12-11", + "value": 29 + }, + { + "date": "2025-12-17", + "value": 32 + }, + { + "date": "2026-01-06", + "value": 26 + }, + { + "date": "2026-01-12", + "value": 29 + }, + { + "date": "2026-01-18", + "value": 31 + }, + { + "date": "2026-02-04", + "value": 33 + }, + { + "date": "2026-02-10", + "value": 36 + }, + { + "date": "2026-02-16", + "value": 39 + }, + { + "date": "2026-03-05", + "value": 33 + }, + { + "date": "2026-03-11", + "value": 36 + }, + { + "date": "2026-03-17", + "value": 23 + }, + { + "date": "2026-04-06", + "value": 40 + }, + { + "date": "2026-04-12", + "value": 27 + }, + { + "date": "2026-04-18", + "value": 31 + }, + { + "date": "2026-05-04", + "value": 24 + }, + { + "date": "2026-05-10", + "value": 27 + }, + { + "date": "2026-05-16", + "value": 29 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-08", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 32.0, + "median": 32.0, + "p10": 32.0, + "p25": 32.0, + "p75": 32.0, + "p90": 32.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 45.0, + "median": 45.0, + "p10": 45.0, + "p25": 45.0, + "p75": 45.0, + "p90": 45.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 34.8, + "median": 37.0, + "p10": 29.0, + "p25": 33.5, + "p75": 38.3, + "p90": 38.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 28.3, + "median": 26.0, + "p10": 23.6, + "p25": 24.5, + "p75": 31.0, + "p90": 34.0, + "n": 3 + }, + { + "month": "2025-11", + "mean": 30.3, + "median": 31.0, + "p10": 27.8, + "p25": 29.0, + "p75": 32.0, + "p90": 32.6, + "n": 3 + }, + { + "month": "2025-12", + "mean": 29.3, + "median": 29.0, + "p10": 27.4, + "p25": 28.0, + "p75": 30.5, + "p90": 31.4, + "n": 3 + }, + { + "month": "2026-01", + "mean": 28.7, + "median": 29.0, + "p10": 26.6, + "p25": 27.5, + "p75": 30.0, + "p90": 30.6, + "n": 3 + }, + { + "month": "2026-02", + "mean": 36.0, + "median": 36.0, + "p10": 33.6, + "p25": 34.5, + "p75": 37.5, + "p90": 38.4, + "n": 3 + }, + { + "month": "2026-03", + "mean": 30.7, + "median": 33.0, + "p10": 25.0, + "p25": 28.0, + "p75": 34.5, + "p90": 35.4, + "n": 3 + }, + { + "month": "2026-04", + "mean": 32.7, + "median": 31.0, + "p10": 27.8, + "p25": 29.0, + "p75": 35.5, + "p90": 38.2, + "n": 3 + }, + { + "month": "2026-05", + "mean": 26.7, + "median": 27.0, + "p10": 24.6, + "p25": 25.5, + "p75": 28.0, + "p90": 28.6, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 45.0, + "median": 44.0, + "std": 14.0, + "min": 10, + "max": 95, + "p25": 36.0, + "p75": 49.0, + "p85": 53.0, + "p95": 67.6 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 28.5, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 42 + }, + { + "date": "2023-05-05", + "value": 65 + }, + { + "date": "2023-05-20", + "value": 28 + }, + { + "date": "2024-01-10", + "value": 95 + }, + { + "date": "2024-01-25", + "value": 35 + }, + { + "date": "2024-08-15", + "value": 10 + }, + { + "date": "2025-02-05", + "value": 78 + }, + { + "date": "2025-02-18", + "value": 55 + }, + { + "date": "2025-08-10", + "value": 42 + }, + { + "date": "2025-08-20", + "value": 32 + }, + { + "date": "2025-09-06", + "value": 39 + }, + { + "date": "2025-09-12", + "value": 42 + }, + { + "date": "2025-09-18", + "value": 46 + }, + { + "date": "2025-10-04", + "value": 49 + }, + { + "date": "2025-10-10", + "value": 53 + }, + { + "date": "2025-10-16", + "value": 57 + }, + { + "date": "2025-11-05", + "value": 48 + }, + { + "date": "2025-11-11", + "value": 52 + }, + { + "date": "2025-11-17", + "value": 34 + }, + { + "date": "2025-12-06", + "value": 48 + }, + { + "date": "2025-12-12", + "value": 30 + }, + { + "date": "2025-12-18", + "value": 34 + }, + { + "date": "2026-01-04", + "value": 36 + }, + { + "date": "2026-01-10", + "value": 41 + }, + { + "date": "2026-01-16", + "value": 43 + }, + { + "date": "2026-02-05", + "value": 36 + }, + { + "date": "2026-02-11", + "value": 39 + }, + { + "date": "2026-02-17", + "value": 42 + }, + { + "date": "2026-03-06", + "value": 46 + }, + { + "date": "2026-03-12", + "value": 49 + }, + { + "date": "2026-03-18", + "value": 53 + }, + { + "date": "2026-04-04", + "value": 45 + }, + { + "date": "2026-04-10", + "value": 48 + }, + { + "date": "2026-04-16", + "value": 52 + }, + { + "date": "2026-05-05", + "value": 44 + }, + { + "date": "2026-05-11", + "value": 48 + }, + { + "date": "2026-05-17", + "value": 30 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 46.5, + "median": 46.5, + "p10": 31.7, + "p25": 37.3, + "p75": 55.8, + "p90": 61.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 65.0, + "median": 65.0, + "p10": 41.0, + "p25": 50.0, + "p75": 80.0, + "p90": 89.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 66.5, + "median": 66.5, + "p10": 57.3, + "p25": 60.8, + "p75": 72.3, + "p90": 75.7, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 37.0, + "median": 37.0, + "p10": 33.0, + "p25": 34.5, + "p75": 39.5, + "p90": 41.0, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 42.3, + "median": 42.0, + "p10": 39.6, + "p25": 40.5, + "p75": 44.0, + "p90": 45.2, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 53.0, + "median": 53.0, + "p10": 49.8, + "p25": 51.0, + "p75": 55.0, + "p90": 56.2, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 44.7, + "median": 48.0, + "p10": 36.8, + "p25": 41.0, + "p75": 50.0, + "p90": 51.2, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 37.3, + "median": 34.0, + "p10": 30.8, + "p25": 32.0, + "p75": 41.0, + "p90": 45.2, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 40.0, + "median": 41.0, + "p10": 37.0, + "p25": 38.5, + "p75": 42.0, + "p90": 42.6, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 39.0, + "median": 39.0, + "p10": 36.6, + "p25": 37.5, + "p75": 40.5, + "p90": 41.4, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 49.3, + "median": 49.0, + "p10": 46.6, + "p25": 47.5, + "p75": 51.0, + "p90": 52.2, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 48.3, + "median": 48.0, + "p10": 45.6, + "p25": 46.5, + "p75": 50.0, + "p90": 51.2, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 40.7, + "median": 44.0, + "p10": 32.8, + "p25": 37.0, + "p75": 46.0, + "p90": 47.2, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ], + "edges": [ + { + "source": "procurement_highland_arabica", + "target": "raw_dwell_highland_arabica", + "label": "101" + }, + { + "source": "procurement_lowland_robusta", + "target": "raw_dwell_lowland_robusta", + "label": "101" + }, + { + "source": "procurement_washed_bourbon", + "target": "raw_dwell_washed_bourbon", + "label": "101" + }, + { + "source": "raw_dwell_highland_arabica", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "raw_dwell_lowland_robusta", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "prod_duration_green_blend", + "target": "intermed_dwell_green_blend", + "label": "101" + }, + { + "source": "raw_dwell_washed_bourbon", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "intermed_dwell_green_blend", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "prod_duration_harbor_dark_roast", + "target": "prod_to_qa_pla", + "label": "101" + }, + { + "source": "post_qa_ship_pla", + "target": "direct_ship_pla", + "label": "601" + }, + { + "source": "post_qa_ship_pla", + "target": "transit_pla_hub1", + "label": "641" + }, + { + "source": "transit_pla_hub1", + "target": "dest_dwell_hub1" + }, + { + "source": "prod_to_qa_pla", + "target": "post_qa_ship_pla" + } + ], + "pipeline_summary": { + "direct": { + "label": "Direct to customer", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 29.9, + "median": 30, + "pct_of_total": 17.6, + "n": 60 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 99.8, + "median": 101, + "pct_of_total": 58.9, + "n": 60 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.6, + "median": 7, + "pct_of_total": 3.9, + "n": 60 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 33.2, + "median": 33, + "pct_of_total": 19.6, + "n": 60 + } + ], + "total_mean": 169.5, + "total_median": 171 + }, + "hub-1": { + "label": "HUB-1", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 28.4, + "median": 29, + "pct_of_total": 12.8, + "n": 40 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 102.1, + "median": 104, + "pct_of_total": 46.1, + "n": 40 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.2, + "median": 6, + "pct_of_total": 2.8, + "n": 40 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 84.8, + "median": 88, + "pct_of_total": 38.3, + "n": 40 + } + ], + "total_mean": 221.5, + "total_median": 227 + } + }, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica", + "step_ids": ["procurement_highland_arabica", "raw_dwell_highland_arabica"] + }, + { + "date": "2024-01-15", + "label": "QA process revision", + "step_ids": ["qa_hold_pla"] + } + ], + "batch_timelines": { + "batches": [ + { + "batch": "BATCH-007069", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-05-27", + "earliest_gr_date": "2024-05-29", + "earliest_production_start": "2024-07-03", + "fg_receipt_date": "2024-10-28", + "qa_release_date": "2024-11-03", + "ship_date": null, + "delivery_date": "2024-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 117, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 112, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 23 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-767678", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-13", + "earliest_gr_date": "2024-07-15", + "earliest_production_start": "2024-07-29", + "fg_receipt_date": "2024-11-05", + "qa_release_date": "2024-11-09", + "ship_date": null, + "delivery_date": "2024-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 99, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 36, + "total_days": 155, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 14, + "direct_ship_pla": 22 + } + }, + "total_from_po": 155 + }, + { + "batch": "BATCH-872783", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-25", + "earliest_gr_date": "2024-07-27", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-08", + "qa_release_date": "2024-11-15", + "ship_date": null, + "delivery_date": "2024-12-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 81, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 35, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 58, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 78, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 25 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-868247", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-20", + "earliest_gr_date": "2024-07-22", + "earliest_production_start": "2024-08-24", + "fg_receipt_date": "2024-11-10", + "qa_release_date": "2024-11-19", + "ship_date": null, + "delivery_date": "2024-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 37, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 61, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "direct_ship_pla": 20 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-775611", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-22", + "earliest_gr_date": "2024-07-24", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-22", + "qa_release_date": "2024-11-30", + "ship_date": null, + "delivery_date": "2024-12-31", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 95, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-544789", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-08", + "earliest_gr_date": "2024-07-10", + "earliest_production_start": "2024-08-05", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-12", + "ship_date": null, + "delivery_date": "2025-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 122, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 7, + "direct_ship_pla": 18 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-447665", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-14", + "earliest_gr_date": "2024-07-16", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-11", + "ship_date": null, + "delivery_date": "2025-01-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 31, + "total_days": 181, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "direct_ship_pla": 18 + } + }, + "total_from_po": 181 + }, + { + "batch": "BATCH-963613", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-26", + "fg_receipt_date": "2024-12-12", + "qa_release_date": "2024-12-19", + "ship_date": null, + "delivery_date": "2025-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 19 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-863299", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-05", + "earliest_gr_date": "2024-08-07", + "earliest_production_start": "2024-08-30", + "fg_receipt_date": "2024-12-21", + "qa_release_date": "2024-12-27", + "ship_date": null, + "delivery_date": "2025-01-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 26, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-528145", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-22", + "earliest_gr_date": "2024-08-24", + "earliest_production_start": "2024-09-11", + "fg_receipt_date": "2024-12-24", + "qa_release_date": "2024-12-30", + "ship_date": null, + "delivery_date": "2025-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 29, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 90, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 102, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 17 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-242499", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-17", + "earliest_gr_date": "2024-08-19", + "earliest_production_start": "2024-09-16", + "fg_receipt_date": "2024-12-26", + "qa_release_date": "2024-12-31", + "ship_date": null, + "delivery_date": "2025-02-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 33, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-576635", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-29", + "earliest_gr_date": "2024-10-01", + "earliest_production_start": "2024-10-26", + "fg_receipt_date": "2024-12-31", + "qa_release_date": "2025-01-07", + "ship_date": null, + "delivery_date": "2025-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 66, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 32, + "total_days": 132, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 47, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 64, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 24 + } + }, + "total_from_po": 132 + }, + { + "batch": "BATCH-221460", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-28", + "fg_receipt_date": "2025-01-01", + "qa_release_date": "2025-01-08", + "ship_date": null, + "delivery_date": "2025-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 126, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 36, + "total_days": 204, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 120, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 78, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 23 + } + }, + "total_from_po": 204 + }, + { + "batch": "BATCH-666578", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-06", + "fg_receipt_date": "2025-01-10", + "qa_release_date": "2025-01-18", + "ship_date": null, + "delivery_date": "2025-02-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-208118", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-19", + "fg_receipt_date": "2025-01-11", + "qa_release_date": "2025-01-19", + "ship_date": null, + "delivery_date": "2025-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 44, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 36, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 51, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 67, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 7, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 38, + "production_days": 7, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 15, + "direct_ship_pla": 21 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-458243", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-04", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-29", + "ship_date": null, + "delivery_date": "2025-03-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-207730", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-16", + "earliest_gr_date": "2024-09-18", + "earliest_production_start": "2024-10-14", + "fg_receipt_date": "2025-01-18", + "qa_release_date": "2025-01-22", + "ship_date": null, + "delivery_date": "2025-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 44, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 92, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 16, + "direct_ship_pla": 28 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-033995", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-27", + "earliest_gr_date": "2024-08-29", + "earliest_production_start": "2024-09-30", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-30", + "ship_date": null, + "delivery_date": "2025-03-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 114, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 18, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 17, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-559161", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-16", + "fg_receipt_date": "2025-02-14", + "qa_release_date": "2025-02-19", + "ship_date": null, + "delivery_date": "2025-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 27, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 10, + "direct_ship_pla": 17 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-043249", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-28", + "earliest_gr_date": "2024-09-30", + "earliest_production_start": "2024-10-27", + "fg_receipt_date": "2025-02-12", + "qa_release_date": "2025-02-15", + "ship_date": null, + "delivery_date": "2025-03-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 36, + "total_days": 176, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 12, + "direct_ship_pla": 24 + } + }, + "total_from_po": 176 + }, + { + "batch": "BATCH-876661", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-05", + "earliest_gr_date": "2024-10-07", + "earliest_production_start": "2024-11-06", + "fg_receipt_date": "2025-02-04", + "qa_release_date": "2025-02-11", + "ship_date": null, + "delivery_date": "2025-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 31 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-758211", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-24", + "earliest_gr_date": "2024-09-26", + "earliest_production_start": "2024-10-24", + "fg_receipt_date": "2025-02-22", + "qa_release_date": "2025-03-01", + "ship_date": null, + "delivery_date": "2025-04-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 191, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 191 + }, + { + "batch": "BATCH-198568", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-07", + "earliest_gr_date": "2024-10-09", + "earliest_production_start": "2024-10-29", + "fg_receipt_date": "2025-02-21", + "qa_release_date": "2025-03-02", + "ship_date": null, + "delivery_date": "2025-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 115, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 38, + "total_days": 184, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 13, + "direct_ship_pla": 25 + } + }, + "total_from_po": 184 + }, + { + "batch": "BATCH-499114", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-20", + "earliest_gr_date": "2024-11-22", + "earliest_production_start": "2024-12-17", + "fg_receipt_date": "2025-03-05", + "qa_release_date": "2025-03-14", + "ship_date": null, + "delivery_date": "2025-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 31, + "total_days": 145, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 33, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 145 + }, + { + "batch": "BATCH-947566", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-15", + "earliest_gr_date": "2024-10-17", + "earliest_production_start": "2024-11-17", + "fg_receipt_date": "2025-03-07", + "qa_release_date": "2025-03-10", + "ship_date": null, + "delivery_date": "2025-04-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 40, + "total_days": 186, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 14, + "direct_ship_pla": 26 + } + }, + "total_from_po": 186 + }, + { + "batch": "BATCH-154390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-25", + "earliest_gr_date": "2024-10-27", + "earliest_production_start": "2024-11-27", + "fg_receipt_date": "2025-03-10", + "qa_release_date": "2025-03-16", + "ship_date": null, + "delivery_date": "2025-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 40, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 22, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 22, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 44, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 28 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-557064", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-01", + "earliest_gr_date": "2024-12-03", + "earliest_production_start": "2025-01-02", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-05", + "ship_date": null, + "delivery_date": "2025-04-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 150, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 150 + }, + { + "batch": "BATCH-307333", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-17", + "earliest_gr_date": "2024-11-19", + "earliest_production_start": "2024-12-15", + "fg_receipt_date": "2025-03-27", + "qa_release_date": "2025-04-04", + "ship_date": null, + "delivery_date": "2025-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 32, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 73, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 16 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-891817", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-02", + "earliest_gr_date": "2024-12-04", + "earliest_production_start": "2024-12-16", + "fg_receipt_date": "2025-03-30", + "qa_release_date": "2025-04-07", + "ship_date": null, + "delivery_date": "2025-05-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 14, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 76, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 25 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-852390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-24", + "earliest_gr_date": "2024-11-26", + "earliest_production_start": "2024-12-29", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-06", + "ship_date": null, + "delivery_date": "2025-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 174, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 27 + } + }, + "total_from_po": 174 + }, + { + "batch": "BATCH-412722", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-31", + "earliest_gr_date": "2025-01-02", + "earliest_production_start": "2025-01-21", + "fg_receipt_date": "2025-04-15", + "qa_release_date": "2025-04-20", + "ship_date": null, + "delivery_date": "2025-05-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 21, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 32, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 9, + "direct_ship_pla": 23 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-357156", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-08", + "earliest_gr_date": "2024-11-10", + "earliest_production_start": "2024-12-13", + "fg_receipt_date": "2025-04-05", + "qa_release_date": "2025-04-13", + "ship_date": null, + "delivery_date": "2025-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 45, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 72, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 83, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 60, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 31 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-851698", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-04", + "earliest_gr_date": "2025-01-06", + "earliest_production_start": "2025-02-06", + "fg_receipt_date": "2025-04-22", + "qa_release_date": "2025-04-30", + "ship_date": null, + "delivery_date": "2025-06-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 75, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 33, + "total_days": 149, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 71, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 54, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 7, + "direct_ship_pla": 26 + } + }, + "total_from_po": 149 + }, + { + "batch": "BATCH-440021", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-29", + "earliest_gr_date": "2024-12-31", + "earliest_production_start": "2025-01-31", + "fg_receipt_date": "2025-05-05", + "qa_release_date": "2025-05-13", + "ship_date": null, + "delivery_date": "2025-06-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 26, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-546123", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-20", + "earliest_gr_date": "2024-12-22", + "earliest_production_start": "2025-01-18", + "fg_receipt_date": "2025-05-08", + "qa_release_date": "2025-05-15", + "ship_date": null, + "delivery_date": "2025-06-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-990560", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-29", + "earliest_gr_date": "2024-12-01", + "earliest_production_start": "2025-01-08", + "fg_receipt_date": "2025-05-16", + "qa_release_date": "2025-05-24", + "ship_date": null, + "delivery_date": "2025-06-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 40, + "seg_prodstart_to_prodfinish": 128, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 25, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 109, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 125, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-386297", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-03", + "earliest_gr_date": "2025-01-05", + "earliest_production_start": "2025-01-29", + "fg_receipt_date": "2025-05-19", + "qa_release_date": "2025-05-26", + "ship_date": null, + "delivery_date": "2025-06-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 50, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 14, + "direct_ship_pla": 15 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-947389", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-21", + "earliest_gr_date": "2025-01-23", + "earliest_production_start": "2025-02-19", + "fg_receipt_date": "2025-05-31", + "qa_release_date": "2025-06-06", + "ship_date": null, + "delivery_date": "2025-06-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 16, + "direct_ship_pla": 7 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-627234", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-26", + "earliest_gr_date": "2025-01-28", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-05-29", + "qa_release_date": "2025-06-01", + "ship_date": null, + "delivery_date": "2025-07-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 11, + "direct_ship_pla": 23 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-829707", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-14", + "earliest_gr_date": "2025-01-16", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-06-01", + "qa_release_date": "2025-06-09", + "ship_date": null, + "delivery_date": "2025-07-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 42, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-404324", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-22", + "earliest_gr_date": "2025-02-24", + "earliest_production_start": "2025-03-24", + "fg_receipt_date": "2025-06-18", + "qa_release_date": "2025-06-27", + "ship_date": null, + "delivery_date": "2025-07-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 19, + "total_days": 144, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 65, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 83, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 9, + "direct_ship_pla": 10 + } + }, + "total_from_po": 144 + }, + { + "batch": "BATCH-840018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-10", + "earliest_gr_date": "2025-02-12", + "earliest_production_start": "2025-03-15", + "fg_receipt_date": "2025-06-17", + "qa_release_date": "2025-06-21", + "ship_date": null, + "delivery_date": "2025-07-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 30, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 77, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 12, + "direct_ship_pla": 18 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-243511", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-11", + "earliest_gr_date": "2025-01-13", + "earliest_production_start": "2025-02-13", + "fg_receipt_date": "2025-06-13", + "qa_release_date": "2025-06-22", + "ship_date": null, + "delivery_date": "2025-07-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 35, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 116, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 53, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-394495", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-07", + "earliest_gr_date": "2025-02-09", + "earliest_production_start": "2025-03-14", + "fg_receipt_date": "2025-06-24", + "qa_release_date": "2025-07-02", + "ship_date": null, + "delivery_date": "2025-08-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 30, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 21 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-043032", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-15", + "earliest_gr_date": "2025-02-17", + "earliest_production_start": "2025-03-11", + "fg_receipt_date": "2025-06-29", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 33, + "total_days": 173, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 41, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 173 + }, + { + "batch": "BATCH-582158", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-26", + "earliest_gr_date": "2025-02-28", + "earliest_production_start": "2025-03-23", + "fg_receipt_date": "2025-06-28", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 38, + "total_days": 167, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 23 + } + }, + "total_from_po": 167 + }, + { + "batch": "BATCH-302264", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-30", + "earliest_gr_date": "2025-04-01", + "earliest_production_start": "2025-04-24", + "fg_receipt_date": "2025-07-16", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-08-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 24, + "total_days": 140, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 59, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 77, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 8 + } + }, + "total_from_po": 140 + }, + { + "batch": "BATCH-240076", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-14", + "qa_release_date": "2025-07-21", + "ship_date": null, + "delivery_date": "2025-08-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 151, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 151 + }, + { + "batch": "BATCH-804779", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-20", + "earliest_gr_date": "2025-02-22", + "earliest_production_start": "2025-03-22", + "fg_receipt_date": "2025-07-05", + "qa_release_date": "2025-07-12", + "ship_date": null, + "delivery_date": "2025-08-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 105, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 47, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 12, + "direct_ship_pla": 35 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-731192", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-15", + "earliest_gr_date": "2025-03-17", + "earliest_production_start": "2025-04-23", + "fg_receipt_date": "2025-07-22", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-09-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 39, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 38, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 27 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-482639", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-21", + "earliest_gr_date": "2025-02-23", + "earliest_production_start": "2025-03-30", + "fg_receipt_date": "2025-07-17", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-09-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 199, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "direct_ship_pla": 27 + } + }, + "total_from_po": 199 + }, + { + "batch": "BATCH-062870", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-01", + "earliest_gr_date": "2025-04-03", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-01", + "qa_release_date": "2025-08-07", + "ship_date": null, + "delivery_date": "2025-09-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 38, + "total_days": 166, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 87, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 26 + } + }, + "total_from_po": 166 + }, + { + "batch": "BATCH-231165", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-05", + "earliest_gr_date": "2025-05-07", + "earliest_production_start": "2025-06-09", + "fg_receipt_date": "2025-08-16", + "qa_release_date": "2025-08-22", + "ship_date": null, + "delivery_date": "2025-09-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 68, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 28, + "total_days": 137, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 43, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 14 + } + }, + "total_from_po": 137 + }, + { + "batch": "BATCH-213839", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-23", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-09-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 29, + "total_days": 164, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 47, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 164 + }, + { + "batch": "BATCH-750018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-11", + "earliest_gr_date": "2025-05-13", + "earliest_production_start": "2025-06-05", + "fg_receipt_date": "2025-08-31", + "qa_release_date": "2025-09-06", + "ship_date": null, + "delivery_date": "2025-09-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 87, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 24, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 6, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 6, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "direct_ship_pla": 17 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-880539", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-20", + "earliest_gr_date": "2025-04-22", + "earliest_production_start": "2025-05-26", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-10-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 85, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 41, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 68, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 28 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-155177", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-02", + "earliest_gr_date": "2025-05-04", + "earliest_production_start": "2025-06-18", + "fg_receipt_date": "2025-09-10", + "qa_release_date": "2025-09-16", + "ship_date": null, + "delivery_date": "2025-10-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 47, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 25, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-993261", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-29", + "earliest_gr_date": "2025-05-01", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-08-30", + "qa_release_date": "2025-09-04", + "ship_date": null, + "delivery_date": "2025-10-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 98, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 42, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 72, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 77, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 31 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-753433", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-27", + "earliest_gr_date": "2025-05-29", + "earliest_production_start": "2025-06-13", + "fg_receipt_date": "2025-09-23", + "qa_release_date": "2025-09-29", + "ship_date": null, + "delivery_date": "2025-10-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 8, + "direct_ship_pla": 15 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-476897", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-21", + "earliest_gr_date": "2025-04-23", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-09-14", + "qa_release_date": "2025-09-20", + "ship_date": null, + "delivery_date": "2025-10-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 25 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-521582", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-18", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-11-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 98, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 70, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 43, + "dest_dwell_hub1": 41 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-281803", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-07", + "fg_receipt_date": "2025-07-28", + "qa_release_date": "2025-08-01", + "ship_date": null, + "delivery_date": "2025-11-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 82, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 98, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-276962", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-05", + "earliest_gr_date": "2025-04-07", + "earliest_production_start": "2025-05-05", + "fg_receipt_date": "2025-08-17", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-11-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 79, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 101, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-217426", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-15", + "earliest_gr_date": "2025-04-17", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-08-24", + "qa_release_date": "2025-09-03", + "ship_date": null, + "delivery_date": "2025-11-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 10, + "seg_qa_to_customer": 76, + "total_days": 217, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 72, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 10, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 18, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 217 + }, + { + "batch": "BATCH-679445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-01", + "earliest_gr_date": "2025-05-03", + "earliest_production_start": "2025-06-03", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-11-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 77, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 62, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 36 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-584703", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-19", + "earliest_gr_date": "2025-04-21", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-09-06", + "qa_release_date": "2025-09-13", + "ship_date": null, + "delivery_date": "2025-11-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 77, + "total_days": 224, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 224 + }, + { + "batch": "BATCH-320907", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-03", + "earliest_gr_date": "2025-05-05", + "earliest_production_start": "2025-06-01", + "fg_receipt_date": "2025-08-12", + "qa_release_date": "2025-08-21", + "ship_date": null, + "delivery_date": "2025-12-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 72, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 106, + "total_days": 216, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 54, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 69, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 216 + }, + { + "batch": "BATCH-469894", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-09", + "earliest_gr_date": "2025-04-11", + "earliest_production_start": "2025-05-12", + "fg_receipt_date": "2025-08-29", + "qa_release_date": "2025-09-05", + "ship_date": null, + "delivery_date": "2025-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 96, + "total_days": 245, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 45, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 245 + }, + { + "batch": "BATCH-119167", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-10", + "earliest_gr_date": "2025-05-12", + "earliest_production_start": "2025-05-30", + "fg_receipt_date": "2025-09-19", + "qa_release_date": "2025-09-26", + "ship_date": null, + "delivery_date": "2025-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 80, + "total_days": 219, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 95, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 74, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 219 + }, + { + "batch": "BATCH-850977", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-17", + "earliest_gr_date": "2025-05-19", + "earliest_production_start": "2025-06-14", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-10-01", + "ship_date": null, + "delivery_date": "2025-12-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 81, + "total_days": 218, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 42, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 39 + } + }, + "total_from_po": 218 + }, + { + "batch": "BATCH-315004", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-21", + "earliest_gr_date": "2025-06-23", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-10-06", + "qa_release_date": "2025-10-14", + "ship_date": null, + "delivery_date": "2025-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 71, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 73, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 22, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-753733", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-04", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-09-28", + "ship_date": null, + "delivery_date": "2026-01-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 95, + "total_days": 211, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 80, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 52 + } + }, + "total_from_po": 211 + }, + { + "batch": "BATCH-006984", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-29", + "earliest_gr_date": "2025-05-31", + "earliest_production_start": "2025-06-15", + "fg_receipt_date": "2025-09-20", + "qa_release_date": "2025-09-27", + "ship_date": null, + "delivery_date": "2026-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 101, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 45, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 49 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-962763", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-06", + "fg_receipt_date": "2025-10-26", + "qa_release_date": "2025-11-02", + "ship_date": null, + "delivery_date": "2026-01-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 71, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 35 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-885445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-06-29", + "fg_receipt_date": "2025-10-03", + "qa_release_date": "2025-10-04", + "ship_date": null, + "delivery_date": "2026-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 1, + "seg_qa_to_customer": 105, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 1, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 63 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-622159", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-31", + "earliest_gr_date": "2025-06-02", + "earliest_production_start": "2025-06-26", + "fg_receipt_date": "2025-10-17", + "qa_release_date": "2025-10-23", + "ship_date": null, + "delivery_date": "2026-01-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 92, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-990714", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-03", + "earliest_gr_date": "2025-06-05", + "earliest_production_start": "2025-07-02", + "fg_receipt_date": "2025-10-14", + "qa_release_date": "2025-10-18", + "ship_date": null, + "delivery_date": "2026-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 102, + "total_days": 239, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 239 + }, + { + "batch": "BATCH-479016", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-14", + "earliest_gr_date": "2025-06-16", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-13", + "qa_release_date": "2025-11-19", + "ship_date": null, + "delivery_date": "2026-02-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 118, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 76, + "total_days": 234, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 96, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 114, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 34 + } + }, + "total_from_po": 234 + }, + { + "batch": "BATCH-080863", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-26", + "earliest_gr_date": "2025-06-28", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-12", + "ship_date": null, + "delivery_date": "2026-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 88, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-910231", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-05", + "earliest_gr_date": "2025-07-07", + "earliest_production_start": "2025-08-11", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-16", + "ship_date": null, + "delivery_date": "2026-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 84, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 75, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 86, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-997425", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-07", + "earliest_gr_date": "2025-08-09", + "earliest_production_start": "2025-09-06", + "fg_receipt_date": "2025-12-04", + "qa_release_date": "2025-12-12", + "ship_date": null, + "delivery_date": "2026-02-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 69, + "total_days": 196, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 24, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 37, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 30 + } + }, + "total_from_po": 196 + }, + { + "batch": "BATCH-618940", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-19", + "earliest_gr_date": "2025-06-21", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-11-29", + "qa_release_date": "2025-12-02", + "ship_date": null, + "delivery_date": "2026-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 125, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 84, + "total_days": 250, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 104, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 121, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 43, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 250 + }, + { + "batch": "BATCH-029240", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-14", + "earliest_gr_date": "2025-07-16", + "earliest_production_start": "2025-08-02", + "fg_receipt_date": "2025-11-19", + "qa_release_date": "2025-11-25", + "ship_date": null, + "delivery_date": "2026-03-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 231, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 77, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 44, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 231 + }, + { + "batch": "BATCH-013796", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-04", + "qa_release_date": "2026-01-13", + "ship_date": null, + "delivery_date": "2026-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 53, + "total_days": 202, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 27, + "dest_dwell_hub1": 15 + } + }, + "total_from_po": 202 + }, + { + "batch": "BATCH-563928", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-16", + "fg_receipt_date": "2025-12-08", + "qa_release_date": "2025-12-11", + "ship_date": null, + "delivery_date": "2026-03-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 92, + "total_days": 208, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 208 + }, + { + "batch": "BATCH-263609", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-12", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-10", + "ship_date": null, + "delivery_date": "2026-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 67, + "total_days": 215, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 20, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 15, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 215 + }, + { + "batch": "BATCH-786903", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-30", + "earliest_gr_date": "2025-09-01", + "earliest_production_start": "2025-09-23", + "fg_receipt_date": "2026-01-22", + "qa_release_date": "2026-01-28", + "ship_date": null, + "delivery_date": "2026-03-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 55, + "total_days": 206, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 103, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 17, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 17, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 206 + }, + { + "batch": "BATCH-676932", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-13", + "fg_receipt_date": "2025-12-19", + "qa_release_date": "2025-12-25", + "ship_date": null, + "delivery_date": "2026-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 94, + "total_days": 226, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 35, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 51, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 226 + }, + { + "batch": "BATCH-341567", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-10", + "earliest_gr_date": "2025-08-12", + "earliest_production_start": "2025-09-05", + "fg_receipt_date": "2025-12-27", + "qa_release_date": "2026-01-01", + "ship_date": null, + "delivery_date": "2026-04-04", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 93, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 23, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-162748", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-25", + "earliest_gr_date": "2025-08-27", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-09", + "ship_date": null, + "delivery_date": "2026-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 90, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 33, + "dest_dwell_hub1": 46 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-322485", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-08", + "earliest_gr_date": "2025-10-10", + "earliest_production_start": "2025-10-27", + "fg_receipt_date": "2026-02-01", + "qa_release_date": "2026-02-10", + "ship_date": null, + "delivery_date": "2026-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 63, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 36, + "dest_dwell_hub1": 16 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-780123", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-02", + "earliest_gr_date": "2025-09-04", + "earliest_production_start": "2025-10-02", + "fg_receipt_date": "2026-01-31", + "qa_release_date": "2026-02-08", + "ship_date": null, + "delivery_date": "2026-04-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 71, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 101, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-219665", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-06", + "earliest_gr_date": "2025-10-08", + "earliest_production_start": "2025-10-22", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 69, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 4, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-254225", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-08", + "earliest_gr_date": "2025-09-10", + "earliest_production_start": "2025-09-30", + "fg_receipt_date": "2026-01-28", + "qa_release_date": "2026-02-03", + "ship_date": null, + "delivery_date": "2026-05-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 87, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 115, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-311884", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-12", + "earliest_gr_date": "2025-09-14", + "earliest_production_start": "2025-10-10", + "fg_receipt_date": "2026-01-29", + "qa_release_date": "2026-02-04", + "ship_date": null, + "delivery_date": "2026-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 91, + "total_days": 236, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 236 + }, + { + "batch": "BATCH-534136", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-26", + "earliest_gr_date": "2025-09-28", + "earliest_production_start": "2025-11-08", + "fg_receipt_date": "2026-02-10", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 43, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 86, + "total_days": 228, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 40, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 228 + }, + { + "batch": "BATCH-718060", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-29", + "earliest_gr_date": "2025-10-01", + "earliest_production_start": "2025-11-09", + "fg_receipt_date": "2026-02-24", + "qa_release_date": "2026-02-28", + "ship_date": null, + "delivery_date": "2026-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 41, + "seg_prodstart_to_prodfinish": 107, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 78, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 103, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 14, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-802602", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-12", + "earliest_gr_date": "2025-10-14", + "earliest_production_start": "2025-11-04", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 51 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-136204", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-05", + "earliest_gr_date": "2025-10-07", + "earliest_production_start": "2025-11-05", + "fg_receipt_date": "2026-02-25", + "qa_release_date": "2026-03-03", + "ship_date": null, + "delivery_date": "2026-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 86, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 53, + "dest_dwell_hub1": 19 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-949254", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-14", + "earliest_gr_date": "2025-10-16", + "earliest_production_start": "2025-11-18", + "fg_receipt_date": "2026-02-19", + "qa_release_date": "2026-02-24", + "ship_date": null, + "delivery_date": "2026-06-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 93, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 99, + "total_days": 232, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 74, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 89, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 55 + } + }, + "total_from_po": 232 + } + ], + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.3, + "median": 30, + "p25": 25, + "p75": 34, + "n": 100 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 100.7, + "median": 102, + "p25": 90, + "p75": 112, + "n": 100 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.5, + "median": 7, + "p25": 6, + "p75": 8, + "n": 100 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 53.8, + "median": 40, + "p25": 31, + "p75": 81, + "n": 100 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 190.3, + "median": 188, + "p25": 167, + "p75": 222, + "n": 100 + } + }, + "per_route": { + "direct": { + "label": "Direct to customer", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.9, + "median": 30, + "p25": 26, + "p75": 35, + "n": 60 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 99.8, + "median": 101, + "p25": 90, + "p75": 110, + "n": 60 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.6, + "median": 7, + "p25": 6, + "p75": 8, + "n": 60 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 33.2, + "median": 33, + "p25": 29, + "p75": 38, + "n": 60 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 169.5, + "median": 170, + "p25": 159, + "p75": 182, + "n": 60 + } + } + }, + "hub-1": { + "label": "HUB-1", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 28.4, + "median": 29, + "p25": 24, + "p75": 33, + "n": 40 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 102.1, + "median": 104, + "p25": 96, + "p75": 113, + "n": 40 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.2, + "median": 6, + "p25": 5, + "p75": 8, + "n": 40 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 84.8, + "median": 88, + "p25": 76, + "p75": 96, + "n": 40 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 221.6, + "median": 223, + "p25": 215, + "p75": 232, + "n": 40 + } + } + } + }, + "coverage": { + "traced": 100, + "total": 100 + } + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/dest_dwell_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/dest_dwell_hub1.json new file mode 100644 index 00000000000..a462af363e4 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/dest_dwell_hub1.json @@ -0,0 +1,431 @@ +{ + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "durations": [ + 42, 65, 28, 95, 35, 10, 78, 55, 42, 32, 39, 42, 46, 49, 53, 57, 48, 52, 34, + 48, 30, 34, 36, 41, 43, 36, 39, 42, 46, 49, 53, 45, 48, 52, 44, 48, 30 + ], + "observations": [ + { + "date": "2022-09-15", + "value": 42 + }, + { + "date": "2023-05-05", + "value": 65 + }, + { + "date": "2023-05-20", + "value": 28 + }, + { + "date": "2024-01-10", + "value": 95 + }, + { + "date": "2024-01-25", + "value": 35 + }, + { + "date": "2024-08-15", + "value": 10 + }, + { + "date": "2025-02-05", + "value": 78 + }, + { + "date": "2025-02-18", + "value": 55 + }, + { + "date": "2025-08-10", + "value": 42 + }, + { + "date": "2025-08-20", + "value": 32 + }, + { + "date": "2025-09-06", + "value": 39 + }, + { + "date": "2025-09-12", + "value": 42 + }, + { + "date": "2025-09-18", + "value": 46 + }, + { + "date": "2025-10-04", + "value": 49 + }, + { + "date": "2025-10-10", + "value": 53 + }, + { + "date": "2025-10-16", + "value": 57 + }, + { + "date": "2025-11-05", + "value": 48 + }, + { + "date": "2025-11-11", + "value": 52 + }, + { + "date": "2025-11-17", + "value": 34 + }, + { + "date": "2025-12-06", + "value": 48 + }, + { + "date": "2025-12-12", + "value": 30 + }, + { + "date": "2025-12-18", + "value": 34 + }, + { + "date": "2026-01-04", + "value": 36 + }, + { + "date": "2026-01-10", + "value": 41 + }, + { + "date": "2026-01-16", + "value": 43 + }, + { + "date": "2026-02-05", + "value": 36 + }, + { + "date": "2026-02-11", + "value": 39 + }, + { + "date": "2026-02-17", + "value": 42 + }, + { + "date": "2026-03-06", + "value": 46 + }, + { + "date": "2026-03-12", + "value": 49 + }, + { + "date": "2026-03-18", + "value": 53 + }, + { + "date": "2026-04-04", + "value": 45 + }, + { + "date": "2026-04-10", + "value": 48 + }, + { + "date": "2026-04-16", + "value": 52 + }, + { + "date": "2026-05-05", + "value": 44 + }, + { + "date": "2026-05-11", + "value": 48 + }, + { + "date": "2026-05-17", + "value": 30 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 46.5, + "median": 46.5, + "p10": 31.7, + "p25": 37.3, + "p75": 55.8, + "p90": 61.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 65.0, + "median": 65.0, + "p10": 41.0, + "p25": 50.0, + "p75": 80.0, + "p90": 89.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 66.5, + "median": 66.5, + "p10": 57.3, + "p25": 60.8, + "p75": 72.3, + "p90": 75.7, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 37.0, + "median": 37.0, + "p10": 33.0, + "p25": 34.5, + "p75": 39.5, + "p90": 41.0, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 42.3, + "median": 42.0, + "p10": 39.6, + "p25": 40.5, + "p75": 44.0, + "p90": 45.2, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 53.0, + "median": 53.0, + "p10": 49.8, + "p25": 51.0, + "p75": 55.0, + "p90": 56.2, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 44.7, + "median": 48.0, + "p10": 36.8, + "p25": 41.0, + "p75": 50.0, + "p90": 51.2, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 37.3, + "median": 34.0, + "p10": 30.8, + "p25": 32.0, + "p75": 41.0, + "p90": 45.2, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 40.0, + "median": 41.0, + "p10": 37.0, + "p25": 38.5, + "p75": 42.0, + "p90": 42.6, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 39.0, + "median": 39.0, + "p10": 36.6, + "p25": 37.5, + "p75": 40.5, + "p90": 41.4, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 49.3, + "median": 49.0, + "p10": 46.6, + "p25": 47.5, + "p75": 51.0, + "p90": 52.2, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 48.3, + "median": 48.0, + "p10": 45.6, + "p25": 46.5, + "p75": 50.0, + "p90": 51.2, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 40.7, + "median": 44.0, + "p10": 32.8, + "p25": 37.0, + "p75": 46.0, + "p90": 47.2, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "stats": { + "n": 37, + "mean": 45.0, + "median": 44.0, + "std": 14.0, + "min": 10, + "max": 95, + "p25": 36.0, + "p75": 49.0, + "p85": 53.0, + "p95": 67.6 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 28.5, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/intermed_dwell_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/intermed_dwell_green_blend.json new file mode 100644 index 00000000000..13a276de7e2 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/intermed_dwell_green_blend.json @@ -0,0 +1,593 @@ +{ + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "durations": [ + 12, 25, 8, 35, 15, 5, 22, 18, 40, 10, 55, 2, 28, 15, 8, 20, 45, 12, 3, 18, + 30, 8, 22, 35, 5, 15, 42, 10, 14, 16, 17, 18, 19, 14, 15, 16, 18, 11, 18, + 19, 20, 14, 15, 17, 19, 12, 14, 15, 17, 11, 12, 13, 14, 13, 14, 16, 17, 18, + 13, 14, 15, 16, 18, 16, 18, 19, 20, 14, 16, 17, 19, 12, 14 + ], + "observations": [ + { + "date": "2022-05-05", + "value": 12 + }, + { + "date": "2022-05-15", + "value": 25 + }, + { + "date": "2022-05-22", + "value": 8 + }, + { + "date": "2022-11-03", + "value": 35 + }, + { + "date": "2022-11-10", + "value": 15 + }, + { + "date": "2022-11-18", + "value": 5 + }, + { + "date": "2022-11-25", + "value": 22 + }, + { + "date": "2023-05-08", + "value": 18 + }, + { + "date": "2023-05-15", + "value": 40 + }, + { + "date": "2023-05-22", + "value": 10 + }, + { + "date": "2023-11-06", + "value": 55 + }, + { + "date": "2023-11-13", + "value": 2 + }, + { + "date": "2023-11-20", + "value": 28 + }, + { + "date": "2023-11-27", + "value": 15 + }, + { + "date": "2023-11-30", + "value": 8 + }, + { + "date": "2024-05-06", + "value": 20 + }, + { + "date": "2024-05-13", + "value": 45 + }, + { + "date": "2024-05-20", + "value": 12 + }, + { + "date": "2024-05-27", + "value": 3 + }, + { + "date": "2024-11-04", + "value": 18 + }, + { + "date": "2024-11-11", + "value": 30 + }, + { + "date": "2024-11-18", + "value": 8 + }, + { + "date": "2025-05-05", + "value": 22 + }, + { + "date": "2025-05-09", + "value": 35 + }, + { + "date": "2025-05-13", + "value": 5 + }, + { + "date": "2025-05-17", + "value": 15 + }, + { + "date": "2025-05-21", + "value": 42 + }, + { + "date": "2025-05-25", + "value": 10 + }, + { + "date": "2025-09-05", + "value": 14 + }, + { + "date": "2025-09-11", + "value": 16 + }, + { + "date": "2025-09-17", + "value": 17 + }, + { + "date": "2025-09-23", + "value": 18 + }, + { + "date": "2025-09-29", + "value": 19 + }, + { + "date": "2025-10-06", + "value": 14 + }, + { + "date": "2025-10-12", + "value": 15 + }, + { + "date": "2025-10-18", + "value": 16 + }, + { + "date": "2025-10-24", + "value": 18 + }, + { + "date": "2025-10-30", + "value": 11 + }, + { + "date": "2025-11-04", + "value": 18 + }, + { + "date": "2025-11-10", + "value": 19 + }, + { + "date": "2025-11-16", + "value": 20 + }, + { + "date": "2025-11-22", + "value": 14 + }, + { + "date": "2025-11-28", + "value": 15 + }, + { + "date": "2025-12-05", + "value": 17 + }, + { + "date": "2025-12-11", + "value": 19 + }, + { + "date": "2025-12-17", + "value": 12 + }, + { + "date": "2025-12-23", + "value": 14 + }, + { + "date": "2025-12-29", + "value": 15 + }, + { + "date": "2026-01-06", + "value": 17 + }, + { + "date": "2026-01-12", + "value": 11 + }, + { + "date": "2026-01-18", + "value": 12 + }, + { + "date": "2026-01-24", + "value": 13 + }, + { + "date": "2026-01-30", + "value": 14 + }, + { + "date": "2026-02-04", + "value": 13 + }, + { + "date": "2026-02-10", + "value": 14 + }, + { + "date": "2026-02-16", + "value": 16 + }, + { + "date": "2026-02-22", + "value": 17 + }, + { + "date": "2026-02-28", + "value": 18 + }, + { + "date": "2026-03-05", + "value": 13 + }, + { + "date": "2026-03-11", + "value": 14 + }, + { + "date": "2026-03-17", + "value": 15 + }, + { + "date": "2026-03-23", + "value": 16 + }, + { + "date": "2026-03-29", + "value": 18 + }, + { + "date": "2026-04-06", + "value": 16 + }, + { + "date": "2026-04-12", + "value": 18 + }, + { + "date": "2026-04-18", + "value": 19 + }, + { + "date": "2026-04-24", + "value": 20 + }, + { + "date": "2026-04-30", + "value": 14 + }, + { + "date": "2026-05-04", + "value": 16 + }, + { + "date": "2026-05-10", + "value": 17 + }, + { + "date": "2026-05-16", + "value": 19 + }, + { + "date": "2026-05-22", + "value": 12 + }, + { + "date": "2026-05-28", + "value": 14 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 15.0, + "median": 12.0, + "p10": 8.8, + "p25": 10.0, + "p75": 18.5, + "p90": 22.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 19.3, + "median": 18.5, + "p10": 8.0, + "p25": 12.5, + "p75": 25.3, + "p90": 31.1, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 22.7, + "median": 18.0, + "p10": 11.6, + "p25": 14.0, + "p75": 29.0, + "p90": 35.6, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 21.6, + "median": 15.0, + "p10": 4.4, + "p25": 8.0, + "p75": 28.0, + "p90": 44.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 20.0, + "median": 16.0, + "p10": 5.7, + "p25": 9.8, + "p75": 26.3, + "p90": 37.5, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 18.7, + "median": 18.0, + "p10": 10.0, + "p25": 13.0, + "p75": 24.0, + "p90": 27.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 21.5, + "median": 18.5, + "p10": 7.5, + "p25": 11.3, + "p75": 31.8, + "p90": 38.5, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 16.8, + "median": 17.0, + "p10": 14.8, + "p25": 16.0, + "p75": 18.0, + "p90": 18.6, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 14.8, + "median": 15.0, + "p10": 12.2, + "p25": 14.0, + "p75": 16.0, + "p90": 17.2, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 17.2, + "median": 18.0, + "p10": 14.4, + "p25": 15.0, + "p75": 19.0, + "p90": 19.6, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 15.4, + "median": 15.0, + "p10": 12.8, + "p25": 14.0, + "p75": 17.0, + "p90": 18.2, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 13.4, + "median": 13.0, + "p10": 11.4, + "p25": 12.0, + "p75": 14.0, + "p90": 15.8, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 15.6, + "median": 16.0, + "p10": 13.4, + "p25": 14.0, + "p75": 17.0, + "p90": 17.6, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 15.2, + "median": 15.0, + "p10": 13.4, + "p25": 14.0, + "p75": 16.0, + "p90": 17.2, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 17.4, + "median": 18.0, + "p10": 14.8, + "p25": 16.0, + "p75": 19.0, + "p90": 19.6, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 15.6, + "median": 16.0, + "p10": 12.8, + "p25": 14.0, + "p75": 17.0, + "p90": 18.2, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "stats": { + "n": 73, + "mean": 17.4, + "median": 16.0, + "std": 9.0, + "min": 2, + "max": 55, + "p25": 13.0, + "p75": 19.0, + "p85": 20.4, + "p95": 37.0 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "annotations": [], + "cost": { + "unit_price": 12.5, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 28, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/post_qa_ship_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/post_qa_ship_pla.json new file mode 100644 index 00000000000..f77088ef6ee --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/post_qa_ship_pla.json @@ -0,0 +1,512 @@ +{ + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "durations": [ + 8, 22, 42, 6, 18, 28, 12, 2, 15, 5, 20, 4, 14, 15, 10, 11, 12, 14, 8, 10, + 11, 11, 10, 12, 12, 13, 14, 10, 11, 12, 13, 14, 13, 14, 15, 16, 11, 13, 14, + 15, 10, 11, 13, 14, 8, 10, 11, 16, 10, 12, 12, 13, 9, 10, 11, 12, 13 + ], + "observations": [ + { + "date": "2023-03-10", + "value": 8 + }, + { + "date": "2023-03-25", + "value": 22 + }, + { + "date": "2023-09-20", + "value": 42 + }, + { + "date": "2024-03-15", + "value": 6 + }, + { + "date": "2024-03-28", + "value": 18 + }, + { + "date": "2024-09-05", + "value": 28 + }, + { + "date": "2024-09-15", + "value": 12 + }, + { + "date": "2024-09-25", + "value": 2 + }, + { + "date": "2025-03-10", + "value": 15 + }, + { + "date": "2025-03-22", + "value": 5 + }, + { + "date": "2025-07-08", + "value": 20 + }, + { + "date": "2025-07-22", + "value": 4 + }, + { + "date": "2025-09-05", + "value": 14 + }, + { + "date": "2025-09-11", + "value": 15 + }, + { + "date": "2025-09-17", + "value": 10 + }, + { + "date": "2025-09-23", + "value": 11 + }, + { + "date": "2025-09-29", + "value": 12 + }, + { + "date": "2025-10-06", + "value": 14 + }, + { + "date": "2025-10-12", + "value": 8 + }, + { + "date": "2025-10-18", + "value": 10 + }, + { + "date": "2025-10-24", + "value": 11 + }, + { + "date": "2025-10-30", + "value": 11 + }, + { + "date": "2025-11-04", + "value": 10 + }, + { + "date": "2025-11-10", + "value": 12 + }, + { + "date": "2025-11-16", + "value": 12 + }, + { + "date": "2025-11-22", + "value": 13 + }, + { + "date": "2025-11-28", + "value": 14 + }, + { + "date": "2025-12-05", + "value": 10 + }, + { + "date": "2025-12-11", + "value": 11 + }, + { + "date": "2025-12-17", + "value": 12 + }, + { + "date": "2025-12-23", + "value": 13 + }, + { + "date": "2025-12-29", + "value": 14 + }, + { + "date": "2026-01-06", + "value": 13 + }, + { + "date": "2026-01-12", + "value": 14 + }, + { + "date": "2026-01-18", + "value": 15 + }, + { + "date": "2026-01-24", + "value": 16 + }, + { + "date": "2026-01-30", + "value": 11 + }, + { + "date": "2026-02-04", + "value": 13 + }, + { + "date": "2026-02-10", + "value": 14 + }, + { + "date": "2026-02-16", + "value": 15 + }, + { + "date": "2026-02-22", + "value": 10 + }, + { + "date": "2026-02-28", + "value": 11 + }, + { + "date": "2026-03-05", + "value": 13 + }, + { + "date": "2026-03-11", + "value": 14 + }, + { + "date": "2026-03-17", + "value": 8 + }, + { + "date": "2026-03-23", + "value": 10 + }, + { + "date": "2026-03-29", + "value": 11 + }, + { + "date": "2026-04-06", + "value": 16 + }, + { + "date": "2026-04-12", + "value": 10 + }, + { + "date": "2026-04-18", + "value": 12 + }, + { + "date": "2026-04-24", + "value": 12 + }, + { + "date": "2026-04-30", + "value": 13 + }, + { + "date": "2026-05-04", + "value": 9 + }, + { + "date": "2026-05-10", + "value": 10 + }, + { + "date": "2026-05-16", + "value": 11 + }, + { + "date": "2026-05-22", + "value": 12 + }, + { + "date": "2026-05-28", + "value": 13 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 15.0, + "median": 15.0, + "p10": 9.4, + "p25": 11.5, + "p75": 18.5, + "p90": 20.6, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 12.0, + "median": 12.0, + "p10": 7.2, + "p25": 9.0, + "p75": 15.0, + "p90": 16.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 14.0, + "median": 12.0, + "p10": 4.0, + "p25": 7.0, + "p75": 20.0, + "p90": 24.8, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 10.0, + "median": 10.0, + "p10": 6.0, + "p25": 7.5, + "p75": 12.5, + "p90": 14.0, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 12.0, + "median": 12.0, + "p10": 5.6, + "p25": 8.0, + "p75": 16.0, + "p90": 18.4, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 12.4, + "median": 12.0, + "p10": 10.4, + "p25": 11.0, + "p75": 14.0, + "p90": 14.6, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 10.8, + "median": 11.0, + "p10": 8.8, + "p25": 10.0, + "p75": 11.0, + "p90": 12.8, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 12.2, + "median": 12.0, + "p10": 10.8, + "p25": 12.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 12.0, + "median": 12.0, + "p10": 10.4, + "p25": 11.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 13.8, + "median": 14.0, + "p10": 11.8, + "p25": 13.0, + "p75": 15.0, + "p90": 15.6, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 12.6, + "median": 13.0, + "p10": 10.4, + "p25": 11.0, + "p75": 14.0, + "p90": 14.6, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 11.2, + "median": 11.0, + "p10": 8.8, + "p25": 10.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 12.6, + "median": 12.0, + "p10": 10.8, + "p25": 12.0, + "p75": 13.0, + "p90": 14.8, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 11.0, + "median": 11.0, + "p10": 9.4, + "p25": 10.0, + "p75": 12.0, + "p90": 12.6, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "stats": { + "n": 57, + "mean": 12.7, + "median": 12.0, + "std": 5.6, + "min": 2, + "max": 42, + "p25": 10.0, + "p75": 14.0, + "p85": 15.0, + "p95": 20.4 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 28.5, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 12, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_highland_arabica.json new file mode 100644 index 00000000000..015f7c06cb1 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_highland_arabica.json @@ -0,0 +1,3303 @@ +{ + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "durations": [ + 55, 42, 8, 63, 38, 22, 71, 30, 45, 18, 105, 35, 12, 48, 39, 41, 44, 48, 51, + 37, 40, 44, 47, 31, 36, 40, 43, 27, 31, 46, 49, 33, 37, 39, 45, 29, 33, 35, + 38, 35, 39, 41, 44, 48, 35, 37, 40, 44, 47, 33, 36, 40, 43, 27, 42, 46, 49, + 33, 37 + ], + "observations": [ + { + "date": "2022-03-15", + "value": 55 + }, + { + "date": "2022-06-10", + "value": 42 + }, + { + "date": "2022-09-22", + "value": 8 + }, + { + "date": "2022-12-05", + "value": 63 + }, + { + "date": "2023-02-14", + "value": 38 + }, + { + "date": "2023-05-30", + "value": 22 + }, + { + "date": "2023-08-17", + "value": 71 + }, + { + "date": "2023-11-02", + "value": 30 + }, + { + "date": "2024-01-25", + "value": 45 + }, + { + "date": "2024-04-11", + "value": 18 + }, + { + "date": "2024-07-09", + "value": 105 + }, + { + "date": "2024-10-03", + "value": 35 + }, + { + "date": "2025-01-20", + "value": 12 + }, + { + "date": "2025-04-08", + "value": 48 + }, + { + "date": "2025-09-05", + "value": 39 + }, + { + "date": "2025-09-11", + "value": 41 + }, + { + "date": "2025-09-17", + "value": 44 + }, + { + "date": "2025-09-23", + "value": 48 + }, + { + "date": "2025-09-29", + "value": 51 + }, + { + "date": "2025-10-06", + "value": 37 + }, + { + "date": "2025-10-12", + "value": 40 + }, + { + "date": "2025-10-18", + "value": 44 + }, + { + "date": "2025-10-24", + "value": 47 + }, + { + "date": "2025-10-30", + "value": 31 + }, + { + "date": "2025-11-04", + "value": 36 + }, + { + "date": "2025-11-10", + "value": 40 + }, + { + "date": "2025-11-16", + "value": 43 + }, + { + "date": "2025-11-22", + "value": 27 + }, + { + "date": "2025-11-28", + "value": 31 + }, + { + "date": "2025-12-05", + "value": 46 + }, + { + "date": "2025-12-11", + "value": 49 + }, + { + "date": "2025-12-17", + "value": 33 + }, + { + "date": "2025-12-23", + "value": 37 + }, + { + "date": "2025-12-29", + "value": 39 + }, + { + "date": "2026-01-06", + "value": 45 + }, + { + "date": "2026-01-12", + "value": 29 + }, + { + "date": "2026-01-18", + "value": 33 + }, + { + "date": "2026-01-24", + "value": 35 + }, + { + "date": "2026-01-30", + "value": 38 + }, + { + "date": "2026-02-04", + "value": 35 + }, + { + "date": "2026-02-10", + "value": 39 + }, + { + "date": "2026-02-16", + "value": 41 + }, + { + "date": "2026-02-22", + "value": 44 + }, + { + "date": "2026-02-28", + "value": 48 + }, + { + "date": "2026-03-05", + "value": 35 + }, + { + "date": "2026-03-11", + "value": 37 + }, + { + "date": "2026-03-17", + "value": 40 + }, + { + "date": "2026-03-23", + "value": 44 + }, + { + "date": "2026-03-29", + "value": 47 + }, + { + "date": "2026-04-06", + "value": 33 + }, + { + "date": "2026-04-12", + "value": 36 + }, + { + "date": "2026-04-18", + "value": 40 + }, + { + "date": "2026-04-24", + "value": 43 + }, + { + "date": "2026-04-30", + "value": 27 + }, + { + "date": "2026-05-04", + "value": 42 + }, + { + "date": "2026-05-10", + "value": 46 + }, + { + "date": "2026-05-16", + "value": 49 + }, + { + "date": "2026-05-22", + "value": 33 + }, + { + "date": "2026-05-28", + "value": 37 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1 + }, + { + "month": "2022-09", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2022-12", + "mean": 63.0, + "median": 63.0, + "p10": 63.0, + "p25": 63.0, + "p75": 63.0, + "p90": 63.0, + "n": 1 + }, + { + "month": "2023-02", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 71.0, + "median": 71.0, + "p10": 71.0, + "p25": 71.0, + "p75": 71.0, + "p90": 71.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 45.0, + "median": 45.0, + "p10": 45.0, + "p25": 45.0, + "p75": 45.0, + "p90": 45.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 105.0, + "median": 105.0, + "p10": 105.0, + "p25": 105.0, + "p75": 105.0, + "p90": 105.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 44.6, + "median": 44.0, + "p10": 39.8, + "p25": 41.0, + "p75": 48.0, + "p90": 49.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 39.8, + "median": 40.0, + "p10": 33.4, + "p25": 37.0, + "p75": 44.0, + "p90": 45.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 35.4, + "median": 36.0, + "p10": 28.6, + "p25": 31.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 40.8, + "median": 39.0, + "p10": 34.6, + "p25": 37.0, + "p75": 46.0, + "p90": 47.8, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.0, + "median": 35.0, + "p10": 30.6, + "p25": 33.0, + "p75": 38.0, + "p90": 42.2, + "n": 5 + }, + { + "month": "2026-02", + "mean": 41.4, + "median": 41.0, + "p10": 36.6, + "p25": 39.0, + "p75": 44.0, + "p90": 46.4, + "n": 5 + }, + { + "month": "2026-03", + "mean": 40.6, + "median": 40.0, + "p10": 35.8, + "p25": 37.0, + "p75": 44.0, + "p90": 45.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 35.8, + "median": 36.0, + "p10": 29.4, + "p25": 33.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2026-05", + "mean": 41.4, + "median": 42.0, + "p10": 34.6, + "p25": 37.0, + "p75": 46.0, + "p90": 47.8, + "n": 5 + } + ], + "stats": { + "n": 59, + "mean": 40.2, + "median": 40.0, + "std": 13.3, + "min": 8, + "max": 105, + "p25": 35.0, + "p75": 45.0, + "p85": 48.0, + "p95": 55.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_highland_arabica", + "po_number": "4500000003", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000003", + "first_gr_date": "2025-06-03", + "days_vs_promised": -2, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000000", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000000", + "first_gr_date": "2025-06-06", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000005", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000005", + "first_gr_date": "2025-06-13", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000001", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000001", + "first_gr_date": "2025-06-15", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000002", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000002", + "first_gr_date": "2025-06-20", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000004", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000004", + "first_gr_date": "2025-06-21", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000006", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000006", + "first_gr_date": "2025-07-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000007", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000007", + "first_gr_date": "2025-07-10", + "days_vs_promised": 4, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000009", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000009", + "first_gr_date": "2025-07-21", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000010", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000010", + "first_gr_date": "2025-07-26", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000008", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000008", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000012", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000012", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000013", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000013", + "first_gr_date": "2025-08-20", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000014", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000014", + "first_gr_date": "2025-08-23", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000011", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000011", + "first_gr_date": "2025-08-25", + "days_vs_promised": 6, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000015", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000015", + "first_gr_date": "2025-08-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000016", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000016", + "first_gr_date": "2025-09-25", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000019", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000019", + "first_gr_date": "2025-09-27", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000020", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000020", + "first_gr_date": "2025-10-03", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000017", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000017", + "first_gr_date": "2025-10-05", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000018", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000018", + "first_gr_date": "2025-10-10", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000022", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000022", + "first_gr_date": "2025-10-16", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000021", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000021", + "first_gr_date": "2025-10-19", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000023", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000023", + "first_gr_date": "2025-10-31", + "days_vs_promised": 2, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000024", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000024", + "first_gr_date": "2025-11-01", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000025", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000025", + "first_gr_date": "2025-11-17", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000027", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000027", + "first_gr_date": "2025-11-29", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000028", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000028", + "first_gr_date": "2025-12-03", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000026", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000026", + "first_gr_date": "2025-12-04", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000029", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000029", + "first_gr_date": "2025-12-19", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000030", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000030", + "first_gr_date": "2025-12-24", + "days_vs_promised": 1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000034", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000034", + "first_gr_date": "2026-01-11", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000031", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000031", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000033", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000033", + "first_gr_date": "2026-01-13", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000035", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000035", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000032", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000032", + "first_gr_date": "2026-01-17", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000036", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000036", + "first_gr_date": "2026-01-31", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000037", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000037", + "first_gr_date": "2026-02-08", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000038", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000038", + "first_gr_date": "2026-02-11", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000040", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000040", + "first_gr_date": "2026-02-25", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000039", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000039", + "first_gr_date": "2026-03-01", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000041", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000041", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000042", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000042", + "first_gr_date": "2026-03-18", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000043", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000043", + "first_gr_date": "2026-03-22", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000044", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000044", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000045", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000045", + "first_gr_date": "2026-03-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000057", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000057", + "first_gr_date": "2026-04-01", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000068", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000068", + "first_gr_date": "2026-04-07", + "days_vs_promised": 4, + "lead_time_days": 42 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000069", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000069", + "first_gr_date": "2026-04-09", + "days_vs_promised": 3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000056", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000056", + "first_gr_date": "2026-04-10", + "days_vs_promised": 1, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000058", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000058", + "first_gr_date": "2026-04-12", + "days_vs_promised": 5, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000071", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000071", + "first_gr_date": "2026-04-13", + "days_vs_promised": -3, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000060", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000060", + "first_gr_date": "2026-04-14", + "days_vs_promised": 1, + "lead_time_days": 21 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000048", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000048", + "first_gr_date": "2026-04-22", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000050", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000050", + "first_gr_date": "2026-04-27", + "days_vs_promised": -3, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000046", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000046", + "first_gr_date": "2026-04-29", + "days_vs_promised": 3, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000047", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000047", + "first_gr_date": "2026-05-01", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000059", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000059", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000049", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000049", + "first_gr_date": "2026-05-06", + "days_vs_promised": -3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000074", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000074", + "first_gr_date": "2026-05-06", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000063", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000063", + "first_gr_date": "2026-05-07", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000051", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000051", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000070", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000070", + "first_gr_date": "2026-05-12", + "days_vs_promised": 20, + "lead_time_days": 64 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000075", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000075", + "first_gr_date": "2026-05-15", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000061", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000061", + "first_gr_date": "2026-05-18", + "days_vs_promised": -3, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000065", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000065", + "first_gr_date": "2026-05-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000072", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000072", + "first_gr_date": "2026-05-21", + "days_vs_promised": 18, + "lead_time_days": 58 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000062", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000062", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000053", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000053", + "first_gr_date": "2026-05-29", + "days_vs_promised": 0, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000077", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000077", + "first_gr_date": "2026-06-02", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000078", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000078", + "first_gr_date": "2026-06-03", + "days_vs_promised": -3, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000076", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000076", + "first_gr_date": "2026-06-04", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000064", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000064", + "first_gr_date": "2026-06-05", + "days_vs_promised": -1, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000052", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000052", + "first_gr_date": "2026-06-06", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000073", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000073", + "first_gr_date": "2026-06-07", + "days_vs_promised": 30, + "lead_time_days": 68 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000079", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000079", + "first_gr_date": "2026-06-09", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000054", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000054", + "first_gr_date": "2026-06-13", + "days_vs_promised": 0, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000055", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000055", + "first_gr_date": "2026-06-13", + "days_vs_promised": -2, + "lead_time_days": 33 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000066", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000066", + "first_gr_date": "2026-06-16", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000067", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000067", + "first_gr_date": "2026-06-22", + "days_vs_promised": 18, + "lead_time_days": 39 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 14, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0002", + "name": "Cascadia Coffee Traders" + }, + "vendors": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "n_lines": 56, + "n_late": 5, + "on_time_pct": 91.1, + "in_full_pct": 100.0, + "otif_pct": 91.1, + "mean_days_late_all": 0.29, + "mean_days_late_when_late": 3.2, + "median_days_late_when_late": 3, + "max_days_late": 6, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 8.9, + "ge_3d_pct": 5.4, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 12, + "n_late": 4, + "on_time_pct": 66.7, + "in_full_pct": 100.0, + "otif_pct": 66.7, + "mean_days_late_all": 2.08, + "mean_days_late_when_late": 6.2, + "median_days_late_when_late": 3.0, + "max_days_late": 18, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 33.3, + "ge_3d_pct": 16.7, + "ge_7d_pct": 8.3, + "ge_14d_pct": 8.3 + } + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "n_lines": 12, + "n_late": 5, + "on_time_pct": 58.3, + "in_full_pct": 100.0, + "otif_pct": 58.3, + "mean_days_late_all": 6.25, + "mean_days_late_when_late": 15, + "median_days_late_when_late": 18, + "max_days_late": 30, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 41.7, + "ge_3d_pct": 41.7, + "ge_7d_pct": 25.0, + "ge_14d_pct": 25.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 80, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000000", + "po_item": "00010", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "first_gr_date": "2025-06-06", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000001", + "po_item": "00020", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "first_gr_date": "2025-06-15", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000002", + "po_item": "00030", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "first_gr_date": "2025-06-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000003", + "po_item": "00040", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "first_gr_date": "2025-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000004", + "po_item": "00050", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "first_gr_date": "2025-06-21", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000005", + "po_item": "00010", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "first_gr_date": "2025-06-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000006", + "po_item": "00020", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "first_gr_date": "2025-07-09", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000008", + "po_item": "00040", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000009", + "po_item": "00050", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "first_gr_date": "2025-07-21", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000010", + "po_item": "00010", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "first_gr_date": "2025-07-26", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000012", + "po_item": "00030", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000013", + "po_item": "00040", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "first_gr_date": "2025-08-20", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000014", + "po_item": "00050", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "first_gr_date": "2025-08-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000015", + "po_item": "00010", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "first_gr_date": "2025-08-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000016", + "po_item": "00020", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "first_gr_date": "2025-09-25", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000017", + "po_item": "00030", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "first_gr_date": "2025-10-05", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000018", + "po_item": "00040", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "first_gr_date": "2025-10-10", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000019", + "po_item": "00050", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "first_gr_date": "2025-09-27", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000020", + "po_item": "00010", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "first_gr_date": "2025-10-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000021", + "po_item": "00020", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "first_gr_date": "2025-10-19", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000022", + "po_item": "00030", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "first_gr_date": "2025-10-16", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000023", + "po_item": "00040", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-31", + "days_late": 2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000024", + "po_item": "00050", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "first_gr_date": "2025-11-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000025", + "po_item": "00010", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "first_gr_date": "2025-11-17", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000026", + "po_item": "00020", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "first_gr_date": "2025-12-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000027", + "po_item": "00030", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "first_gr_date": "2025-11-29", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000028", + "po_item": "00040", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "first_gr_date": "2025-12-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000029", + "po_item": "00050", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "first_gr_date": "2025-12-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000030", + "po_item": "00010", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-24", + "days_late": 1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000031", + "po_item": "00020", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000032", + "po_item": "00030", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "first_gr_date": "2026-01-17", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000033", + "po_item": "00040", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000034", + "po_item": "00050", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000035", + "po_item": "00010", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000036", + "po_item": "00020", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "first_gr_date": "2026-01-31", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000037", + "po_item": "00030", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "first_gr_date": "2026-02-08", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000038", + "po_item": "00040", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000039", + "po_item": "00050", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "first_gr_date": "2026-03-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000040", + "po_item": "00010", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "first_gr_date": "2026-02-25", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000041", + "po_item": "00020", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000042", + "po_item": "00030", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "first_gr_date": "2026-03-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000043", + "po_item": "00040", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "first_gr_date": "2026-03-22", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000044", + "po_item": "00050", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000045", + "po_item": "00010", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000047", + "po_item": "00030", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-01", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000048", + "po_item": "00040", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "first_gr_date": "2026-04-22", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000049", + "po_item": "00050", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "first_gr_date": "2026-05-06", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000050", + "po_item": "00010", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "first_gr_date": "2026-04-27", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000051", + "po_item": "00020", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000052", + "po_item": "00030", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000053", + "po_item": "00040", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-29", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000054", + "po_item": "00050", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "first_gr_date": "2026-06-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000055", + "po_item": "00010", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "first_gr_date": "2026-06-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000056", + "po_item": "00010", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "first_gr_date": "2026-04-10", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000057", + "po_item": "00020", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "first_gr_date": "2026-04-01", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000059", + "po_item": "00040", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000060", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-14", + "days_late": 1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000061", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-18", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000062", + "po_item": "00020", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000063", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "first_gr_date": "2026-05-07", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000064", + "po_item": "00040", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-05", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000065", + "po_item": "00050", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "first_gr_date": "2026-05-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000066", + "po_item": "00010", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000071", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000074", + "po_item": "00020", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "first_gr_date": "2026-05-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000075", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-15", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000076", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000077", + "po_item": "00050", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "first_gr_date": "2026-06-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000078", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-03", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000079", + "po_item": "00020", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "first_gr_date": "2026-06-09", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_lowland_robusta.json new file mode 100644 index 00000000000..0d9aa5a31d6 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_lowland_robusta.json @@ -0,0 +1,2573 @@ +{ + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "durations": [ + 32, 48, 5, 67, 25, 41, 15, 82, 38, 20, 52, 10, 44, 28, 35, 18, 55, 26, 26, + 29, 31, 34, 37, 26, 28, 31, 33, 36, 33, 36, 38, 42, 28, 32, 35, 38, 24, 28, + 40, 43, 29, 33, 35, 40, 26, 29, 31, 34, 22, 26, 28, 31, 33, 31, 33, 36, 38, + 42, 30, 32, 35, 38, 24 + ], + "observations": [ + { + "date": "2022-02-08", + "value": 32 + }, + { + "date": "2022-04-19", + "value": 48 + }, + { + "date": "2022-07-11", + "value": 5 + }, + { + "date": "2022-09-28", + "value": 67 + }, + { + "date": "2022-12-15", + "value": 25 + }, + { + "date": "2023-03-07", + "value": 41 + }, + { + "date": "2023-05-22", + "value": 15 + }, + { + "date": "2023-08-09", + "value": 82 + }, + { + "date": "2023-10-30", + "value": 38 + }, + { + "date": "2024-01-16", + "value": 20 + }, + { + "date": "2024-03-25", + "value": 52 + }, + { + "date": "2024-06-12", + "value": 10 + }, + { + "date": "2024-08-28", + "value": 44 + }, + { + "date": "2024-11-14", + "value": 28 + }, + { + "date": "2025-01-06", + "value": 35 + }, + { + "date": "2025-03-18", + "value": 18 + }, + { + "date": "2025-05-29", + "value": 55 + }, + { + "date": "2025-08-12", + "value": 26 + }, + { + "date": "2025-09-04", + "value": 26 + }, + { + "date": "2025-09-10", + "value": 29 + }, + { + "date": "2025-09-16", + "value": 31 + }, + { + "date": "2025-09-22", + "value": 34 + }, + { + "date": "2025-09-28", + "value": 37 + }, + { + "date": "2025-10-05", + "value": 26 + }, + { + "date": "2025-10-11", + "value": 28 + }, + { + "date": "2025-10-17", + "value": 31 + }, + { + "date": "2025-10-23", + "value": 33 + }, + { + "date": "2025-10-29", + "value": 36 + }, + { + "date": "2025-11-06", + "value": 33 + }, + { + "date": "2025-11-12", + "value": 36 + }, + { + "date": "2025-11-18", + "value": 38 + }, + { + "date": "2025-11-24", + "value": 42 + }, + { + "date": "2025-11-30", + "value": 28 + }, + { + "date": "2025-12-04", + "value": 32 + }, + { + "date": "2025-12-10", + "value": 35 + }, + { + "date": "2025-12-16", + "value": 38 + }, + { + "date": "2025-12-22", + "value": 24 + }, + { + "date": "2025-12-28", + "value": 28 + }, + { + "date": "2026-01-05", + "value": 40 + }, + { + "date": "2026-01-11", + "value": 43 + }, + { + "date": "2026-01-17", + "value": 29 + }, + { + "date": "2026-01-23", + "value": 33 + }, + { + "date": "2026-01-29", + "value": 35 + }, + { + "date": "2026-02-06", + "value": 40 + }, + { + "date": "2026-02-12", + "value": 26 + }, + { + "date": "2026-02-18", + "value": 29 + }, + { + "date": "2026-02-24", + "value": 31 + }, + { + "date": "2026-02-30", + "value": 34 + }, + { + "date": "2026-03-04", + "value": 22 + }, + { + "date": "2026-03-10", + "value": 26 + }, + { + "date": "2026-03-16", + "value": 28 + }, + { + "date": "2026-03-22", + "value": 31 + }, + { + "date": "2026-03-28", + "value": 33 + }, + { + "date": "2026-04-05", + "value": 31 + }, + { + "date": "2026-04-11", + "value": 33 + }, + { + "date": "2026-04-17", + "value": 36 + }, + { + "date": "2026-04-23", + "value": 38 + }, + { + "date": "2026-04-29", + "value": 42 + }, + { + "date": "2026-05-06", + "value": 30 + }, + { + "date": "2026-05-12", + "value": 32 + }, + { + "date": "2026-05-18", + "value": 35 + }, + { + "date": "2026-05-24", + "value": 38 + }, + { + "date": "2026-05-30", + "value": 24 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 32.0, + "median": 32.0, + "p10": 32.0, + "p25": 32.0, + "p75": 32.0, + "p90": 32.0, + "n": 1 + }, + { + "month": "2022-04", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-09", + "mean": 67.0, + "median": 67.0, + "p10": 67.0, + "p25": 67.0, + "p75": 67.0, + "p90": 67.0, + "n": 1 + }, + { + "month": "2022-12", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 41.0, + "median": 41.0, + "p10": 41.0, + "p25": 41.0, + "p75": 41.0, + "p90": 41.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 82.0, + "median": 82.0, + "p10": 82.0, + "p25": 82.0, + "p75": 82.0, + "p90": 82.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 20.0, + "median": 20.0, + "p10": 20.0, + "p25": 20.0, + "p75": 20.0, + "p90": 20.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 52.0, + "median": 52.0, + "p10": 52.0, + "p25": 52.0, + "p75": 52.0, + "p90": 52.0, + "n": 1 + }, + { + "month": "2024-06", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1 + }, + { + "month": "2024-08", + "mean": 44.0, + "median": 44.0, + "p10": 44.0, + "p25": 44.0, + "p75": 44.0, + "p90": 44.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 31.4, + "median": 31.0, + "p10": 27.2, + "p25": 29.0, + "p75": 34.0, + "p90": 35.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 30.8, + "median": 31.0, + "p10": 26.8, + "p25": 28.0, + "p75": 33.0, + "p90": 34.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 35.4, + "median": 36.0, + "p10": 30.0, + "p25": 33.0, + "p75": 38.0, + "p90": 40.4, + "n": 5 + }, + { + "month": "2025-12", + "mean": 31.4, + "median": 32.0, + "p10": 25.6, + "p25": 28.0, + "p75": 35.0, + "p90": 36.8, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.0, + "median": 35.0, + "p10": 30.6, + "p25": 33.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 32.0, + "median": 31.0, + "p10": 27.2, + "p25": 29.0, + "p75": 34.0, + "p90": 37.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 28.0, + "median": 28.0, + "p10": 23.6, + "p25": 26.0, + "p75": 31.0, + "p90": 32.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 36.0, + "median": 36.0, + "p10": 31.8, + "p25": 33.0, + "p75": 38.0, + "p90": 40.4, + "n": 5 + }, + { + "month": "2026-05", + "mean": 31.8, + "median": 32.0, + "p10": 26.4, + "p25": 30.0, + "p75": 35.0, + "p90": 36.8, + "n": 5 + } + ], + "stats": { + "n": 63, + "mean": 33.4, + "median": 33.0, + "std": 11.4, + "min": 5, + "max": 82, + "p25": 28.0, + "p75": 38.0, + "p85": 40.7, + "p95": 51.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000081", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000081", + "first_gr_date": "2025-08-29", + "days_vs_promised": -1, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000082", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000082", + "first_gr_date": "2025-09-03", + "days_vs_promised": -2, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000080", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000080", + "first_gr_date": "2025-09-08", + "days_vs_promised": -2, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000083", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000083", + "first_gr_date": "2025-09-16", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000084", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000084", + "first_gr_date": "2025-10-01", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000086", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000086", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000088", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000088", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000085", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000085", + "first_gr_date": "2025-10-19", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000087", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000087", + "first_gr_date": "2025-10-22", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000089", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000089", + "first_gr_date": "2025-11-01", + "days_vs_promised": -1, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000090", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000090", + "first_gr_date": "2025-11-06", + "days_vs_promised": -1, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000093", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000093", + "first_gr_date": "2025-11-23", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000094", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000094", + "first_gr_date": "2025-11-25", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000091", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000091", + "first_gr_date": "2025-11-30", + "days_vs_promised": -2, + "lead_time_days": 47 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000092", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000092", + "first_gr_date": "2025-12-07", + "days_vs_promised": -1, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000095", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000095", + "first_gr_date": "2025-12-20", + "days_vs_promised": -3, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000099", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000099", + "first_gr_date": "2025-12-27", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000096", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000096", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000098", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000098", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000097", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000097", + "first_gr_date": "2025-12-30", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000101", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000101", + "first_gr_date": "2026-01-15", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000102", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000102", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000100", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000100", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000122", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000122", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000104", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000104", + "first_gr_date": "2026-02-08", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000103", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000103", + "first_gr_date": "2026-02-13", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000105", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000105", + "first_gr_date": "2026-02-23", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000125", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000125", + "first_gr_date": "2026-02-24", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000123", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000123", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000107", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000107", + "first_gr_date": "2026-03-02", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000124", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000124", + "first_gr_date": "2026-03-07", + "days_vs_promised": -3, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000106", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000106", + "first_gr_date": "2026-03-13", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000126", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000126", + "first_gr_date": "2026-03-14", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000127", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000127", + "first_gr_date": "2026-03-23", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000108", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000108", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000128", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000128", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000110", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000110", + "first_gr_date": "2026-03-25", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000109", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000109", + "first_gr_date": "2026-04-06", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000129", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000129", + "first_gr_date": "2026-04-08", + "days_vs_promised": -3, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000114", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000114", + "first_gr_date": "2026-04-11", + "days_vs_promised": -2, + "lead_time_days": 19 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000111", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000111", + "first_gr_date": "2026-04-12", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000112", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000112", + "first_gr_date": "2026-04-13", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000130", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000130", + "first_gr_date": "2026-04-17", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000115", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000115", + "first_gr_date": "2026-04-23", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000134", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000134", + "first_gr_date": "2026-04-30", + "days_vs_promised": -3, + "lead_time_days": 24 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000113", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000113", + "first_gr_date": "2026-05-01", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000131", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000131", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000117", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000117", + "first_gr_date": "2026-05-05", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000136", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000136", + "first_gr_date": "2026-05-08", + "days_vs_promised": -2, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000132", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000132", + "first_gr_date": "2026-05-09", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000133", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000133", + "first_gr_date": "2026-05-13", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000135", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000135", + "first_gr_date": "2026-05-18", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000116", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000116", + "first_gr_date": "2026-05-21", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000138", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000138", + "first_gr_date": "2026-05-28", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000118", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000118", + "first_gr_date": "2026-05-31", + "days_vs_promised": -1, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000139", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000139", + "first_gr_date": "2026-05-31", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000137", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000137", + "first_gr_date": "2026-06-01", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000120", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000120", + "first_gr_date": "2026-06-05", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000119", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000119", + "first_gr_date": "2026-06-17", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000121", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000121", + "first_gr_date": "2026-06-19", + "days_vs_promised": 0, + "lead_time_days": 37 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 18, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0004", + "name": "Riverbend Reliable Supply" + }, + "vendors": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "n_lines": 42, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "n_lines": 18, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [], + "coverage_pct": 100.0, + "n_lines": 60, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000080", + "po_item": "00010", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "first_gr_date": "2025-09-08", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000081", + "po_item": "00020", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "first_gr_date": "2025-08-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000082", + "po_item": "00030", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "first_gr_date": "2025-09-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000083", + "po_item": "00040", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "first_gr_date": "2025-09-16", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000084", + "po_item": "00050", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "first_gr_date": "2025-10-01", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000085", + "po_item": "00010", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "first_gr_date": "2025-10-19", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000086", + "po_item": "00020", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000087", + "po_item": "00030", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "first_gr_date": "2025-10-22", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000088", + "po_item": "00040", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000089", + "po_item": "00050", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-01", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000090", + "po_item": "00010", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-06", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000091", + "po_item": "00020", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "first_gr_date": "2025-11-30", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000092", + "po_item": "00030", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "first_gr_date": "2025-12-07", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000093", + "po_item": "00040", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "first_gr_date": "2025-11-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000094", + "po_item": "00050", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "first_gr_date": "2025-11-25", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000095", + "po_item": "00010", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-20", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000096", + "po_item": "00020", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000097", + "po_item": "00030", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "first_gr_date": "2025-12-30", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000098", + "po_item": "00040", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000099", + "po_item": "00050", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "first_gr_date": "2025-12-27", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000100", + "po_item": "00010", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000101", + "po_item": "00020", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000102", + "po_item": "00030", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000103", + "po_item": "00040", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-13", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000104", + "po_item": "00050", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "first_gr_date": "2026-02-08", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000105", + "po_item": "00010", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "first_gr_date": "2026-02-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000106", + "po_item": "00020", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "first_gr_date": "2026-03-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000107", + "po_item": "00030", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "first_gr_date": "2026-03-02", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000108", + "po_item": "00040", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000109", + "po_item": "00050", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000110", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-25", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000111", + "po_item": "00020", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "first_gr_date": "2026-04-12", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000112", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-13", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000113", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "first_gr_date": "2026-05-01", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000114", + "po_item": "00050", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-11", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000115", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "first_gr_date": "2026-04-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000116", + "po_item": "00020", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-21", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000117", + "po_item": "00030", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "first_gr_date": "2026-05-05", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000118", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "first_gr_date": "2026-05-31", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000119", + "po_item": "00050", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "first_gr_date": "2026-06-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000120", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "first_gr_date": "2026-06-05", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000121", + "po_item": "00020", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "first_gr_date": "2026-06-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000122", + "po_item": "00010", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000123", + "po_item": "00020", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000124", + "po_item": "00030", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-07", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000125", + "po_item": "00040", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "first_gr_date": "2026-02-24", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000126", + "po_item": "00050", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "first_gr_date": "2026-03-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000127", + "po_item": "00010", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-23", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000128", + "po_item": "00020", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000129", + "po_item": "00030", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-08", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000130", + "po_item": "00040", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "first_gr_date": "2026-04-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000131", + "po_item": "00050", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000132", + "po_item": "00010", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000133", + "po_item": "00020", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "first_gr_date": "2026-05-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000134", + "po_item": "00030", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "first_gr_date": "2026-04-30", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000135", + "po_item": "00040", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000136", + "po_item": "00050", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "first_gr_date": "2026-05-08", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000137", + "po_item": "00010", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "first_gr_date": "2026-06-01", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000138", + "po_item": "00020", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "first_gr_date": "2026-05-28", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000139", + "po_item": "00030", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "first_gr_date": "2026-05-31", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_washed_bourbon.json new file mode 100644 index 00000000000..88afa209359 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/procurement_washed_bourbon.json @@ -0,0 +1,2249 @@ +{ + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "durations": [ + 35, 16, 62, 7, 40, 25, 48, 12, 30, 14, 30, 19, 22, 23, 25, 23, 25, 27, 29, + 31, 23, 25, 27, 29, 31, 22, 24, 26, 28, 18, 28, 30, 32, 22, 24, 27, 30, 19, + 22, 23, 34, 23, 25, 27, 29, 20, 23, 25, 27, 29, 20, 22, 24, 26, 28 + ], + "observations": [ + { + "date": "2022-05-03", + "value": 35 + }, + { + "date": "2022-10-18", + "value": 16 + }, + { + "date": "2023-01-24", + "value": 62 + }, + { + "date": "2023-06-15", + "value": 7 + }, + { + "date": "2023-09-28", + "value": 40 + }, + { + "date": "2024-02-12", + "value": 25 + }, + { + "date": "2024-05-07", + "value": 48 + }, + { + "date": "2024-09-19", + "value": 12 + }, + { + "date": "2025-02-04", + "value": 30 + }, + { + "date": "2025-06-10", + "value": 14 + }, + { + "date": "2025-09-06", + "value": 30 + }, + { + "date": "2025-09-12", + "value": 19 + }, + { + "date": "2025-09-18", + "value": 22 + }, + { + "date": "2025-09-24", + "value": 23 + }, + { + "date": "2025-09-30", + "value": 25 + }, + { + "date": "2025-10-04", + "value": 23 + }, + { + "date": "2025-10-10", + "value": 25 + }, + { + "date": "2025-10-16", + "value": 27 + }, + { + "date": "2025-10-22", + "value": 29 + }, + { + "date": "2025-10-28", + "value": 31 + }, + { + "date": "2025-11-05", + "value": 23 + }, + { + "date": "2025-11-11", + "value": 25 + }, + { + "date": "2025-11-17", + "value": 27 + }, + { + "date": "2025-11-23", + "value": 29 + }, + { + "date": "2025-11-29", + "value": 31 + }, + { + "date": "2025-12-06", + "value": 22 + }, + { + "date": "2025-12-12", + "value": 24 + }, + { + "date": "2025-12-18", + "value": 26 + }, + { + "date": "2025-12-24", + "value": 28 + }, + { + "date": "2025-12-30", + "value": 18 + }, + { + "date": "2026-01-04", + "value": 28 + }, + { + "date": "2026-01-10", + "value": 30 + }, + { + "date": "2026-01-16", + "value": 32 + }, + { + "date": "2026-01-22", + "value": 22 + }, + { + "date": "2026-01-28", + "value": 24 + }, + { + "date": "2026-02-05", + "value": 27 + }, + { + "date": "2026-02-11", + "value": 30 + }, + { + "date": "2026-02-17", + "value": 19 + }, + { + "date": "2026-02-23", + "value": 22 + }, + { + "date": "2026-02-29", + "value": 23 + }, + { + "date": "2026-03-06", + "value": 34 + }, + { + "date": "2026-03-12", + "value": 23 + }, + { + "date": "2026-03-18", + "value": 25 + }, + { + "date": "2026-03-24", + "value": 27 + }, + { + "date": "2026-03-30", + "value": 29 + }, + { + "date": "2026-04-04", + "value": 20 + }, + { + "date": "2026-04-10", + "value": 23 + }, + { + "date": "2026-04-16", + "value": 25 + }, + { + "date": "2026-04-22", + "value": 27 + }, + { + "date": "2026-04-28", + "value": 29 + }, + { + "date": "2026-05-05", + "value": 20 + }, + { + "date": "2026-05-11", + "value": 22 + }, + { + "date": "2026-05-17", + "value": 24 + }, + { + "date": "2026-05-23", + "value": 26 + }, + { + "date": "2026-05-29", + "value": 28 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 16.0, + "median": 16.0, + "p10": 16.0, + "p25": 16.0, + "p75": 16.0, + "p90": 16.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 62.0, + "median": 62.0, + "p10": 62.0, + "p25": 62.0, + "p75": 62.0, + "p90": 62.0, + "n": 1 + }, + { + "month": "2023-06", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 40.0, + "median": 40.0, + "p10": 40.0, + "p25": 40.0, + "p75": 40.0, + "p90": 40.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2025-02", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 14.0, + "median": 14.0, + "p10": 14.0, + "p25": 14.0, + "p75": 14.0, + "p90": 14.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 23.8, + "median": 23.0, + "p10": 20.2, + "p25": 22.0, + "p75": 25.0, + "p90": 28.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 27.0, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 30.2, + "n": 5 + }, + { + "month": "2025-11", + "mean": 27.0, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 30.2, + "n": 5 + }, + { + "month": "2025-12", + "mean": 23.6, + "median": 24.0, + "p10": 19.6, + "p25": 22.0, + "p75": 26.0, + "p90": 27.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 27.2, + "median": 28.0, + "p10": 22.8, + "p25": 24.0, + "p75": 30.0, + "p90": 31.2, + "n": 5 + }, + { + "month": "2026-02", + "mean": 24.2, + "median": 23.0, + "p10": 20.2, + "p25": 22.0, + "p75": 27.0, + "p90": 28.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 27.6, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 32.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 24.8, + "median": 25.0, + "p10": 21.2, + "p25": 23.0, + "p75": 27.0, + "p90": 28.2, + "n": 5 + }, + { + "month": "2026-05", + "mean": 24.0, + "median": 24.0, + "p10": 20.8, + "p25": 22.0, + "p75": 26.0, + "p90": 27.2, + "n": 5 + } + ], + "stats": { + "n": 55, + "mean": 26.1, + "median": 25.0, + "std": 8.0, + "min": 7, + "max": 62, + "p25": 22.5, + "p75": 29.0, + "p85": 30.0, + "p95": 36.5 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000142", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000142", + "first_gr_date": "2025-10-29", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000141", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000141", + "first_gr_date": "2025-11-02", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000140", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000140", + "first_gr_date": "2025-11-07", + "days_vs_promised": 24, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000143", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000143", + "first_gr_date": "2025-11-07", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000144", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000144", + "first_gr_date": "2025-11-10", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000146", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000146", + "first_gr_date": "2025-12-03", + "days_vs_promised": -2, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000145", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000145", + "first_gr_date": "2025-12-11", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000148", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000148", + "first_gr_date": "2025-12-21", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000147", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000147", + "first_gr_date": "2025-12-23", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000150", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000150", + "first_gr_date": "2026-01-06", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000149", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000149", + "first_gr_date": "2026-01-07", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000151", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000151", + "first_gr_date": "2026-01-13", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000153", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000153", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000155", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000155", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000152", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000152", + "first_gr_date": "2026-01-26", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000154", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000154", + "first_gr_date": "2026-01-31", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000156", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000156", + "first_gr_date": "2026-02-14", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000158", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000158", + "first_gr_date": "2026-02-15", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000157", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000157", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000159", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000159", + "first_gr_date": "2026-03-06", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000176", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000176", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000160", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000160", + "first_gr_date": "2026-03-08", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000175", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000175", + "first_gr_date": "2026-03-10", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000178", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000178", + "first_gr_date": "2026-03-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000161", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000161", + "first_gr_date": "2026-03-20", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000179", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000179", + "first_gr_date": "2026-03-29", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000162", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000162", + "first_gr_date": "2026-04-01", + "days_vs_promised": 12, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000180", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000180", + "first_gr_date": "2026-04-02", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000177", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000177", + "first_gr_date": "2026-04-05", + "days_vs_promised": 2, + "lead_time_days": 47 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000165", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000165", + "first_gr_date": "2026-04-07", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000164", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000164", + "first_gr_date": "2026-04-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000163", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000163", + "first_gr_date": "2026-04-10", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000166", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000166", + "first_gr_date": "2026-04-10", + "days_vs_promised": -1, + "lead_time_days": 24 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000167", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000167", + "first_gr_date": "2026-04-16", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000181", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000181", + "first_gr_date": "2026-04-24", + "days_vs_promised": 0, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000182", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000182", + "first_gr_date": "2026-04-25", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000183", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000183", + "first_gr_date": "2026-04-26", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000168", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000168", + "first_gr_date": "2026-04-30", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000171", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000171", + "first_gr_date": "2026-05-11", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000185", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000185", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000184", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000184", + "first_gr_date": "2026-05-16", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000169", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000169", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000170", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000170", + "first_gr_date": "2026-05-27", + "days_vs_promised": -2, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000174", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000174", + "first_gr_date": "2026-06-03", + "days_vs_promised": -2, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000172", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000172", + "first_gr_date": "2026-06-09", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000186", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000186", + "first_gr_date": "2026-06-15", + "days_vs_promised": 5, + "lead_time_days": 55 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000189", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000189", + "first_gr_date": "2026-06-17", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000187", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000187", + "first_gr_date": "2026-06-18", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000188", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000188", + "first_gr_date": "2026-06-21", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000173", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000173", + "first_gr_date": "2026-07-02", + "days_vs_promised": 8, + "lead_time_days": 58 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0005", + "name": "Midland Mid-Tier Partners" + }, + "vendors": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "n_lines": 35, + "n_late": 4, + "on_time_pct": 88.6, + "in_full_pct": 100.0, + "otif_pct": 88.6, + "mean_days_late_all": 1.29, + "mean_days_late_when_late": 11.2, + "median_days_late_when_late": 10.0, + "max_days_late": 24, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 11.4, + "ge_3d_pct": 8.6, + "ge_7d_pct": 8.6, + "ge_14d_pct": 2.9 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 15, + "n_late": 3, + "on_time_pct": 80.0, + "in_full_pct": 100.0, + "otif_pct": 80.0, + "mean_days_late_all": 0.53, + "mean_days_late_when_late": 2.7, + "median_days_late_when_late": 2, + "max_days_late": 5, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 20.0, + "ge_3d_pct": 6.7, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 50, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000141", + "po_item": "00020", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000142", + "po_item": "00030", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-29", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000143", + "po_item": "00040", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000144", + "po_item": "00050", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "first_gr_date": "2025-11-10", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000145", + "po_item": "00010", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "first_gr_date": "2025-12-11", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000146", + "po_item": "00020", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "first_gr_date": "2025-12-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000147", + "po_item": "00030", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000148", + "po_item": "00040", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "first_gr_date": "2025-12-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000149", + "po_item": "00050", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "first_gr_date": "2026-01-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000150", + "po_item": "00010", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "first_gr_date": "2026-01-06", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000151", + "po_item": "00020", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "first_gr_date": "2026-01-13", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000152", + "po_item": "00030", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "first_gr_date": "2026-01-26", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000153", + "po_item": "00040", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000154", + "po_item": "00050", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "first_gr_date": "2026-01-31", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000155", + "po_item": "00010", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000156", + "po_item": "00020", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "first_gr_date": "2026-02-14", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000157", + "po_item": "00030", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000158", + "po_item": "00040", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "first_gr_date": "2026-02-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000159", + "po_item": "00050", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "first_gr_date": "2026-03-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000160", + "po_item": "00010", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "first_gr_date": "2026-03-08", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000163", + "po_item": "00040", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000164", + "po_item": "00050", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-09", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000165", + "po_item": "00010", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000166", + "po_item": "00020", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-10", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000167", + "po_item": "00030", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000168", + "po_item": "00040", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "first_gr_date": "2026-04-30", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000169", + "po_item": "00050", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000170", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-27", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000171", + "po_item": "00020", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "first_gr_date": "2026-05-11", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000172", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "first_gr_date": "2026-06-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000174", + "po_item": "00050", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "first_gr_date": "2026-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000175", + "po_item": "00010", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000176", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000178", + "po_item": "00040", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-19", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000179", + "po_item": "00050", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "first_gr_date": "2026-03-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000180", + "po_item": "00010", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "first_gr_date": "2026-04-02", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000181", + "po_item": "00020", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "first_gr_date": "2026-04-24", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000182", + "po_item": "00030", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "first_gr_date": "2026-04-25", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000183", + "po_item": "00040", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-26", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000184", + "po_item": "00050", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "first_gr_date": "2026-05-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000185", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000187", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "first_gr_date": "2026-06-18", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000188", + "po_item": "00040", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "first_gr_date": "2026-06-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_green_blend.json new file mode 100644 index 00000000000..0356d40c2c4 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_green_blend.json @@ -0,0 +1,922 @@ +{ + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "durations": [ + 3, 5, 2, 7, 4, 6, 3, 14, 4, 8, 3, 5, 1, 6, 3, 4, 4, 4, 3, 4, 4, 4, 4, 5, 5, + 5, 4, 5, 5, 3, 4, 5, 3, 3, 5, 3, 4, 4, 3, 3, 4, 4, 4, 4, 5, 5, 4, 4, 5, 5 + ], + "observations": [ + { + "date": "2022-04-18", + "value": 3 + }, + { + "date": "2022-07-05", + "value": 5 + }, + { + "date": "2022-10-12", + "value": 2 + }, + { + "date": "2023-01-20", + "value": 7 + }, + { + "date": "2023-04-15", + "value": 4 + }, + { + "date": "2023-07-28", + "value": 6 + }, + { + "date": "2023-10-05", + "value": 3 + }, + { + "date": "2024-01-12", + "value": 14 + }, + { + "date": "2024-04-22", + "value": 4 + }, + { + "date": "2024-07-10", + "value": 8 + }, + { + "date": "2024-10-18", + "value": 3 + }, + { + "date": "2025-01-25", + "value": 5 + }, + { + "date": "2025-05-08", + "value": 1 + }, + { + "date": "2025-08-15", + "value": 6 + }, + { + "date": "2025-09-04", + "value": 3 + }, + { + "date": "2025-09-10", + "value": 4 + }, + { + "date": "2025-09-16", + "value": 4 + }, + { + "date": "2025-09-22", + "value": 4 + }, + { + "date": "2025-10-05", + "value": 3 + }, + { + "date": "2025-10-11", + "value": 4 + }, + { + "date": "2025-10-17", + "value": 4 + }, + { + "date": "2025-10-23", + "value": 4 + }, + { + "date": "2025-11-06", + "value": 4 + }, + { + "date": "2025-11-12", + "value": 5 + }, + { + "date": "2025-11-18", + "value": 5 + }, + { + "date": "2025-11-24", + "value": 5 + }, + { + "date": "2025-12-04", + "value": 4 + }, + { + "date": "2025-12-10", + "value": 5 + }, + { + "date": "2025-12-16", + "value": 5 + }, + { + "date": "2025-12-22", + "value": 3 + }, + { + "date": "2026-01-05", + "value": 4 + }, + { + "date": "2026-01-11", + "value": 5 + }, + { + "date": "2026-01-17", + "value": 3 + }, + { + "date": "2026-01-23", + "value": 3 + }, + { + "date": "2026-02-06", + "value": 5 + }, + { + "date": "2026-02-12", + "value": 3 + }, + { + "date": "2026-02-18", + "value": 4 + }, + { + "date": "2026-02-24", + "value": 4 + }, + { + "date": "2026-03-04", + "value": 3 + }, + { + "date": "2026-03-10", + "value": 3 + }, + { + "date": "2026-03-16", + "value": 4 + }, + { + "date": "2026-03-22", + "value": 4 + }, + { + "date": "2026-04-05", + "value": 4 + }, + { + "date": "2026-04-11", + "value": 4 + }, + { + "date": "2026-04-17", + "value": 5 + }, + { + "date": "2026-04-23", + "value": 5 + }, + { + "date": "2026-05-06", + "value": 4 + }, + { + "date": "2026-05-12", + "value": 4 + }, + { + "date": "2026-05-18", + "value": 5 + }, + { + "date": "2026-05-24", + "value": 5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 14.0, + "median": 14.0, + "p10": 14.0, + "p25": 14.0, + "p75": 14.0, + "p90": 14.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 4.8, + "median": 5.0, + "p10": 4.3, + "p25": 4.8, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 4.3, + "median": 4.5, + "p10": 3.3, + "p25": 3.8, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.8, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.3, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.0, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.3, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 4.5, + "median": 4.5, + "p10": 4.0, + "p25": 4.0, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.5, + "median": 4.5, + "p10": 4.0, + "p25": 4.0, + "p75": 5.0, + "p90": 5.0, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 4.4, + "median": 4.0, + "std": 1.8, + "min": 1, + "max": 14, + "p25": 3.3, + "p75": 5.0, + "p85": 5.0, + "p95": 6.6 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 50, + "n_movements": null, + "yield_data": { + "values": [ + 98.2, 99.5, 97.8, 100.2, 96.5, 99.0, 98.8, 97.2, 99.5, 100.8, 98.0, 97.5, + 99.2, 98.5, 98.4, 98.6, 98.9, 99.1, 98.3, 98.5, 98.8, 99.1, 99.0, 99.3, + 99.6, 98.2, 99.0, 99.3, 97.9, 98.2, 98.9, 97.6, 97.9, 98.1, 98.1, 98.4, + 98.6, 98.9, 98.1, 98.3, 98.5, 98.8, 98.8, 99.0, 99.3, 99.6, 98.7, 99.0, + 99.3, 97.9 + ], + "observations": [ + { + "date": "2022-04-21", + "value": 98.2 + }, + { + "date": "2022-07-10", + "value": 99.5 + }, + { + "date": "2022-10-14", + "value": 97.8 + }, + { + "date": "2023-01-27", + "value": 100.2 + }, + { + "date": "2023-04-19", + "value": 96.5 + }, + { + "date": "2023-08-03", + "value": 99.0 + }, + { + "date": "2023-10-08", + "value": 98.8 + }, + { + "date": "2024-01-26", + "value": 97.2 + }, + { + "date": "2024-04-26", + "value": 99.5 + }, + { + "date": "2024-07-18", + "value": 100.8 + }, + { + "date": "2024-10-21", + "value": 98.0 + }, + { + "date": "2025-01-30", + "value": 97.5 + }, + { + "date": "2025-05-09", + "value": 99.2 + }, + { + "date": "2025-08-21", + "value": 98.5 + }, + { + "date": "2025-09-05", + "value": 98.4 + }, + { + "date": "2025-09-11", + "value": 98.6 + }, + { + "date": "2025-09-17", + "value": 98.9 + }, + { + "date": "2025-09-23", + "value": 99.1 + }, + { + "date": "2025-10-06", + "value": 98.3 + }, + { + "date": "2025-10-12", + "value": 98.5 + }, + { + "date": "2025-10-18", + "value": 98.8 + }, + { + "date": "2025-10-24", + "value": 99.1 + }, + { + "date": "2025-11-04", + "value": 99.0 + }, + { + "date": "2025-11-10", + "value": 99.3 + }, + { + "date": "2025-11-16", + "value": 99.6 + }, + { + "date": "2025-11-22", + "value": 98.2 + }, + { + "date": "2025-12-05", + "value": 99.0 + }, + { + "date": "2025-12-11", + "value": 99.3 + }, + { + "date": "2025-12-17", + "value": 97.9 + }, + { + "date": "2025-12-23", + "value": 98.2 + }, + { + "date": "2026-01-06", + "value": 98.9 + }, + { + "date": "2026-01-12", + "value": 97.6 + }, + { + "date": "2026-01-18", + "value": 97.9 + }, + { + "date": "2026-01-24", + "value": 98.1 + }, + { + "date": "2026-02-04", + "value": 98.1 + }, + { + "date": "2026-02-10", + "value": 98.4 + }, + { + "date": "2026-02-16", + "value": 98.6 + }, + { + "date": "2026-02-22", + "value": 98.9 + }, + { + "date": "2026-03-05", + "value": 98.1 + }, + { + "date": "2026-03-11", + "value": 98.3 + }, + { + "date": "2026-03-17", + "value": 98.5 + }, + { + "date": "2026-03-23", + "value": 98.8 + }, + { + "date": "2026-04-06", + "value": 98.8 + }, + { + "date": "2026-04-12", + "value": 99.0 + }, + { + "date": "2026-04-18", + "value": 99.3 + }, + { + "date": "2026-04-24", + "value": 99.6 + }, + { + "date": "2026-05-04", + "value": 98.7 + }, + { + "date": "2026-05-10", + "value": 99.0 + }, + { + "date": "2026-05-16", + "value": 99.3 + }, + { + "date": "2026-05-22", + "value": 97.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-10", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 96.5, + "median": 96.5, + "p10": 96.5, + "p25": 96.5, + "p75": 96.5, + "p90": 96.5, + "n": 1 + }, + { + "month": "2023-08", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2024-04", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-07", + "mean": 100.8, + "median": 100.8, + "p10": 100.8, + "p25": 100.8, + "p75": 100.8, + "p90": 100.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2025-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 98.8, + "median": 98.8, + "p10": 98.5, + "p25": 98.6, + "p75": 99.0, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 98.7, + "median": 98.7, + "p10": 98.4, + "p25": 98.5, + "p75": 98.9, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.0, + "median": 99.2, + "p10": 98.4, + "p25": 98.8, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 98.6, + "median": 98.6, + "p10": 98.0, + "p25": 98.1, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.1, + "median": 98.0, + "p10": 97.7, + "p25": 97.8, + "p75": 98.3, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 98.5, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.7, + "p90": 98.8, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.4, + "median": 98.4, + "p10": 98.2, + "p25": 98.3, + "p75": 98.6, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 98.7, + "median": 98.9, + "p10": 98.1, + "p25": 98.5, + "p75": 99.1, + "p90": 99.2, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 98.7, + "median": 98.8, + "std": 0.7, + "min": 96.5, + "max": 100.8, + "p25": 98.2, + "p75": 99.1, + "p85": 99.3, + "p95": 99.6 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_harbor_dark_roast.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_harbor_dark_roast.json new file mode 100644 index 00000000000..722ca8a9b3d --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_duration_harbor_dark_roast.json @@ -0,0 +1,1147 @@ +{ + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "durations": [ + 2, 3, 1, 4, 2, 5, 3, 7, 2, 4, 1, 3, 10, 3, 2, 5, 0, 4, 3, 2, 6, 3, 4, 4, 3, + 3, 4, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 4, 3, 3, 3, 4, 4, 4, 4, 3, 3, 4, 2, 3, + 3, 2, 2, 3, 3, 3, 3, 3 + ], + "observations": [ + { + "date": "2022-05-20", + "value": 2 + }, + { + "date": "2022-06-10", + "value": 3 + }, + { + "date": "2022-07-15", + "value": 1 + }, + { + "date": "2022-08-22", + "value": 4 + }, + { + "date": "2022-10-05", + "value": 2 + }, + { + "date": "2022-11-18", + "value": 5 + }, + { + "date": "2023-01-10", + "value": 3 + }, + { + "date": "2023-03-25", + "value": 7 + }, + { + "date": "2023-05-12", + "value": 2 + }, + { + "date": "2023-07-08", + "value": 4 + }, + { + "date": "2023-09-15", + "value": 1 + }, + { + "date": "2023-11-22", + "value": 3 + }, + { + "date": "2024-01-18", + "value": 10 + }, + { + "date": "2024-03-08", + "value": 3 + }, + { + "date": "2024-05-15", + "value": 2 + }, + { + "date": "2024-07-22", + "value": 5 + }, + { + "date": "2024-09-10", + "value": 0 + }, + { + "date": "2024-11-05", + "value": 4 + }, + { + "date": "2025-01-15", + "value": 3 + }, + { + "date": "2025-03-20", + "value": 2 + }, + { + "date": "2025-05-28", + "value": 6 + }, + { + "date": "2025-08-05", + "value": 3 + }, + { + "date": "2025-09-05", + "value": 4 + }, + { + "date": "2025-09-11", + "value": 4 + }, + { + "date": "2025-09-17", + "value": 3 + }, + { + "date": "2025-09-23", + "value": 3 + }, + { + "date": "2025-10-06", + "value": 4 + }, + { + "date": "2025-10-12", + "value": 2 + }, + { + "date": "2025-10-18", + "value": 3 + }, + { + "date": "2025-10-24", + "value": 3 + }, + { + "date": "2025-11-04", + "value": 2 + }, + { + "date": "2025-11-10", + "value": 2 + }, + { + "date": "2025-11-16", + "value": 3 + }, + { + "date": "2025-11-22", + "value": 3 + }, + { + "date": "2025-12-05", + "value": 3 + }, + { + "date": "2025-12-11", + "value": 3 + }, + { + "date": "2025-12-17", + "value": 3 + }, + { + "date": "2025-12-23", + "value": 4 + }, + { + "date": "2026-01-06", + "value": 3 + }, + { + "date": "2026-01-12", + "value": 3 + }, + { + "date": "2026-01-18", + "value": 3 + }, + { + "date": "2026-01-24", + "value": 4 + }, + { + "date": "2026-02-04", + "value": 4 + }, + { + "date": "2026-02-10", + "value": 4 + }, + { + "date": "2026-02-16", + "value": 4 + }, + { + "date": "2026-02-22", + "value": 3 + }, + { + "date": "2026-03-05", + "value": 3 + }, + { + "date": "2026-03-11", + "value": 4 + }, + { + "date": "2026-03-17", + "value": 2 + }, + { + "date": "2026-03-23", + "value": 3 + }, + { + "date": "2026-04-06", + "value": 3 + }, + { + "date": "2026-04-12", + "value": 2 + }, + { + "date": "2026-04-18", + "value": 2 + }, + { + "date": "2026-04-24", + "value": 3 + }, + { + "date": "2026-05-04", + "value": 3 + }, + { + "date": "2026-05-10", + "value": 3 + }, + { + "date": "2026-05-16", + "value": 3 + }, + { + "date": "2026-05-22", + "value": 3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2022-08", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.0, + "p25": 2.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.0, + "p25": 2.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 3.2, + "median": 3.0, + "std": 1.4, + "min": 0, + "max": 10, + "p25": 3.0, + "p75": 4.0, + "p85": 4.0, + "p95": 5.2 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 58, + "n_movements": null, + "yield_data": { + "values": [ + 99.0, 98.5, 99.8, 97.2, 99.5, 98.0, 100.2, 98.8, 99.2, 97.5, 99.0, 98.5, + 100.5, 99.2, 98.0, 97.8, 99.5, 98.2, 99.0, 98.8, 99.5, 97.0, 98.9, 99.1, + 99.4, 99.6, 98.8, 99.0, 99.3, 99.6, 99.5, 99.8, 100.1, 98.7, 99.5, 99.8, + 98.4, 98.7, 99.4, 98.1, 98.4, 98.6, 98.6, 98.9, 99.1, 99.4, 98.6, 98.8, + 99.0, 99.3, 99.3, 99.5, 99.8, 100.1, 99.2, 99.5, 99.8, 98.4 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 99.0 + }, + { + "date": "2022-06-13", + "value": 98.5 + }, + { + "date": "2022-07-16", + "value": 99.8 + }, + { + "date": "2022-08-26", + "value": 97.2 + }, + { + "date": "2022-10-07", + "value": 99.5 + }, + { + "date": "2022-11-23", + "value": 98.0 + }, + { + "date": "2023-01-13", + "value": 100.2 + }, + { + "date": "2023-04-01", + "value": 98.8 + }, + { + "date": "2023-05-14", + "value": 99.2 + }, + { + "date": "2023-07-12", + "value": 97.5 + }, + { + "date": "2023-09-16", + "value": 99.0 + }, + { + "date": "2023-11-25", + "value": 98.5 + }, + { + "date": "2024-01-28", + "value": 100.5 + }, + { + "date": "2024-03-11", + "value": 99.2 + }, + { + "date": "2024-05-17", + "value": 98.0 + }, + { + "date": "2024-07-27", + "value": 97.8 + }, + { + "date": "2024-09-10", + "value": 99.5 + }, + { + "date": "2024-11-09", + "value": 98.2 + }, + { + "date": "2025-01-18", + "value": 99.0 + }, + { + "date": "2025-03-22", + "value": 98.8 + }, + { + "date": "2025-06-03", + "value": 99.5 + }, + { + "date": "2025-08-08", + "value": 97.0 + }, + { + "date": "2025-09-05", + "value": 98.9 + }, + { + "date": "2025-09-11", + "value": 99.1 + }, + { + "date": "2025-09-17", + "value": 99.4 + }, + { + "date": "2025-09-23", + "value": 99.6 + }, + { + "date": "2025-10-06", + "value": 98.8 + }, + { + "date": "2025-10-12", + "value": 99.0 + }, + { + "date": "2025-10-18", + "value": 99.3 + }, + { + "date": "2025-10-24", + "value": 99.6 + }, + { + "date": "2025-11-04", + "value": 99.5 + }, + { + "date": "2025-11-10", + "value": 99.8 + }, + { + "date": "2025-11-16", + "value": 100.1 + }, + { + "date": "2025-11-22", + "value": 98.7 + }, + { + "date": "2025-12-05", + "value": 99.5 + }, + { + "date": "2025-12-11", + "value": 99.8 + }, + { + "date": "2025-12-17", + "value": 98.4 + }, + { + "date": "2025-12-23", + "value": 98.7 + }, + { + "date": "2026-01-06", + "value": 99.4 + }, + { + "date": "2026-01-12", + "value": 98.1 + }, + { + "date": "2026-01-18", + "value": 98.4 + }, + { + "date": "2026-01-24", + "value": 98.6 + }, + { + "date": "2026-02-04", + "value": 98.6 + }, + { + "date": "2026-02-10", + "value": 98.9 + }, + { + "date": "2026-02-16", + "value": 99.1 + }, + { + "date": "2026-02-22", + "value": 99.4 + }, + { + "date": "2026-03-05", + "value": 98.6 + }, + { + "date": "2026-03-11", + "value": 98.8 + }, + { + "date": "2026-03-17", + "value": 99.0 + }, + { + "date": "2026-03-23", + "value": 99.3 + }, + { + "date": "2026-04-06", + "value": 99.3 + }, + { + "date": "2026-04-12", + "value": 99.5 + }, + { + "date": "2026-04-18", + "value": 99.8 + }, + { + "date": "2026-04-24", + "value": 100.1 + }, + { + "date": "2026-05-04", + "value": 99.2 + }, + { + "date": "2026-05-10", + "value": 99.5 + }, + { + "date": "2026-05-16", + "value": 99.8 + }, + { + "date": "2026-05-22", + "value": 98.4 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.8, + "median": 99.8, + "p10": 99.8, + "p25": 99.8, + "p75": 99.8, + "p90": 99.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-11", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2023-07", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 100.5, + "median": 100.5, + "p10": 100.5, + "p25": 100.5, + "p75": 100.5, + "p90": 100.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-11", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 97.0, + "median": 97.0, + "p10": 97.0, + "p25": 97.0, + "p75": 97.0, + "p90": 97.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 99.3, + "median": 99.3, + "p10": 99.0, + "p25": 99.1, + "p75": 99.5, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.5, + "median": 99.7, + "p10": 98.9, + "p25": 99.3, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 99.1, + "median": 99.1, + "p10": 98.5, + "p25": 98.6, + "p75": 99.6, + "p90": 99.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.6, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.8, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-02", + "mean": 99.0, + "median": 99.0, + "p10": 98.7, + "p25": 98.8, + "p75": 99.2, + "p90": 99.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.9, + "median": 98.9, + "p10": 98.7, + "p25": 98.8, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.7, + "median": 99.7, + "p10": 99.4, + "p25": 99.5, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 99.2, + "median": 99.4, + "p10": 98.6, + "p25": 99.0, + "p75": 99.6, + "p90": 99.7, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 99.0, + "median": 99.1, + "std": 0.7, + "min": 97.0, + "max": 100.5, + "p25": 98.6, + "p75": 99.5, + "p85": 99.7, + "p95": 100.1 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_to_qa_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_to_qa_pla.json new file mode 100644 index 00000000000..ab01820e260 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/prod_to_qa_pla.json @@ -0,0 +1,580 @@ +{ + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "durations": [ + 2, 1, 3, 2, 5, 2, 4, 3, 6, 2, 13, 3, 7, 1, 4, 5, 2, 0, 3, 8, 2, 5, 2, 3, 3, + 3, 3, 3, 4, 4, 3, 3, 3, 4, 3, 3, 3, 2, 4, 4, 3, 3, 4, 2, 3, 3, 3, 3, 3, 4, + 3, 3, 3, 3, 3, 3, 3, 3 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 2 + }, + { + "date": "2022-06-13", + "value": 1 + }, + { + "date": "2022-07-16", + "value": 3 + }, + { + "date": "2022-08-26", + "value": 2 + }, + { + "date": "2022-10-07", + "value": 5 + }, + { + "date": "2022-11-23", + "value": 2 + }, + { + "date": "2023-01-13", + "value": 4 + }, + { + "date": "2023-04-01", + "value": 3 + }, + { + "date": "2023-05-14", + "value": 6 + }, + { + "date": "2023-07-12", + "value": 2 + }, + { + "date": "2023-09-16", + "value": 13 + }, + { + "date": "2023-11-25", + "value": 3 + }, + { + "date": "2024-01-28", + "value": 7 + }, + { + "date": "2024-03-11", + "value": 1 + }, + { + "date": "2024-05-17", + "value": 4 + }, + { + "date": "2024-07-27", + "value": 5 + }, + { + "date": "2024-09-10", + "value": 2 + }, + { + "date": "2024-11-09", + "value": 0 + }, + { + "date": "2025-01-18", + "value": 3 + }, + { + "date": "2025-03-22", + "value": 8 + }, + { + "date": "2025-06-03", + "value": 2 + }, + { + "date": "2025-08-08", + "value": 5 + }, + { + "date": "2025-09-04", + "value": 2 + }, + { + "date": "2025-09-10", + "value": 3 + }, + { + "date": "2025-09-16", + "value": 3 + }, + { + "date": "2025-09-22", + "value": 3 + }, + { + "date": "2025-10-05", + "value": 3 + }, + { + "date": "2025-10-11", + "value": 3 + }, + { + "date": "2025-10-17", + "value": 4 + }, + { + "date": "2025-10-23", + "value": 4 + }, + { + "date": "2025-11-06", + "value": 3 + }, + { + "date": "2025-11-12", + "value": 3 + }, + { + "date": "2025-11-18", + "value": 3 + }, + { + "date": "2025-11-24", + "value": 4 + }, + { + "date": "2025-12-04", + "value": 3 + }, + { + "date": "2025-12-10", + "value": 3 + }, + { + "date": "2025-12-16", + "value": 3 + }, + { + "date": "2025-12-22", + "value": 2 + }, + { + "date": "2026-01-05", + "value": 4 + }, + { + "date": "2026-01-11", + "value": 4 + }, + { + "date": "2026-01-17", + "value": 3 + }, + { + "date": "2026-01-23", + "value": 3 + }, + { + "date": "2026-02-06", + "value": 4 + }, + { + "date": "2026-02-12", + "value": 2 + }, + { + "date": "2026-02-18", + "value": 3 + }, + { + "date": "2026-02-24", + "value": 3 + }, + { + "date": "2026-03-04", + "value": 3 + }, + { + "date": "2026-03-10", + "value": 3 + }, + { + "date": "2026-03-16", + "value": 3 + }, + { + "date": "2026-03-22", + "value": 4 + }, + { + "date": "2026-04-05", + "value": 3 + }, + { + "date": "2026-04-11", + "value": 3 + }, + { + "date": "2026-04-17", + "value": 3 + }, + { + "date": "2026-04-23", + "value": 3 + }, + { + "date": "2026-05-06", + "value": 3 + }, + { + "date": "2026-05-12", + "value": 3 + }, + { + "date": "2026-05-18", + "value": 3 + }, + { + "date": "2026-05-24", + "value": 3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 13.0, + "median": 13.0, + "p10": 13.0, + "p25": 13.0, + "p75": 13.0, + "p90": 13.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.8, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.8, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 3.4, + "median": 3.0, + "std": 1.8, + "min": 0, + "max": 13, + "p25": 3.0, + "p75": 4.0, + "p85": 4.0, + "p95": 6.2 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": null, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_highland_arabica.json new file mode 100644 index 00000000000..2814b71a3c7 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_highland_arabica.json @@ -0,0 +1,687 @@ +{ + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "durations": [ + 35, 62, 18, 88, 42, 55, 30, 72, 25, 48, 15, 95, 130, 45, 38, 65, 22, 78, 5, + 55, 40, 28, 85, 50, 110, 32, 68, 45, 92, 20, 58, 35, 42, 75, 12, 48, 60, 38, + 49, 54, 34, 39, 42, 61, 41, 46, 49, 53, 36, 41, 44, 48, 52, 36, 39, 43, 47, + 51, 47, 50, 54, 58, 39, 45, 49, 54, 34, 39, 56, 61, 41, 46, 49, 56, 36, 41, + 44, 48, 32, 36, 39, 43, 47 + ], + "observations": [ + { + "date": "2022-04-02", + "value": 35 + }, + { + "date": "2022-04-15", + "value": 62 + }, + { + "date": "2022-04-28", + "value": 18 + }, + { + "date": "2022-08-05", + "value": 88 + }, + { + "date": "2022-08-12", + "value": 42 + }, + { + "date": "2022-08-20", + "value": 55 + }, + { + "date": "2022-08-28", + "value": 30 + }, + { + "date": "2023-01-10", + "value": 72 + }, + { + "date": "2023-01-22", + "value": 25 + }, + { + "date": "2023-01-30", + "value": 48 + }, + { + "date": "2023-06-05", + "value": 15 + }, + { + "date": "2023-06-18", + "value": 95 + }, + { + "date": "2023-10-03", + "value": 130 + }, + { + "date": "2023-10-10", + "value": 45 + }, + { + "date": "2023-10-18", + "value": 38 + }, + { + "date": "2023-10-25", + "value": 65 + }, + { + "date": "2023-10-30", + "value": 22 + }, + { + "date": "2024-03-05", + "value": 78 + }, + { + "date": "2024-03-12", + "value": 5 + }, + { + "date": "2024-03-20", + "value": 55 + }, + { + "date": "2024-03-28", + "value": 40 + }, + { + "date": "2024-07-08", + "value": 28 + }, + { + "date": "2024-07-15", + "value": 85 + }, + { + "date": "2024-07-22", + "value": 50 + }, + { + "date": "2024-11-04", + "value": 110 + }, + { + "date": "2024-11-11", + "value": 32 + }, + { + "date": "2024-11-18", + "value": 68 + }, + { + "date": "2024-11-25", + "value": 45 + }, + { + "date": "2024-11-30", + "value": 92 + }, + { + "date": "2025-03-03", + "value": 20 + }, + { + "date": "2025-03-10", + "value": 58 + }, + { + "date": "2025-03-17", + "value": 35 + }, + { + "date": "2025-03-24", + "value": 42 + }, + { + "date": "2025-07-02", + "value": 75 + }, + { + "date": "2025-07-09", + "value": 12 + }, + { + "date": "2025-07-16", + "value": 48 + }, + { + "date": "2025-07-23", + "value": 60 + }, + { + "date": "2025-07-30", + "value": 38 + }, + { + "date": "2025-09-05", + "value": 49 + }, + { + "date": "2025-09-11", + "value": 54 + }, + { + "date": "2025-09-17", + "value": 34 + }, + { + "date": "2025-09-23", + "value": 39 + }, + { + "date": "2025-09-29", + "value": 42 + }, + { + "date": "2025-10-06", + "value": 61 + }, + { + "date": "2025-10-12", + "value": 41 + }, + { + "date": "2025-10-18", + "value": 46 + }, + { + "date": "2025-10-24", + "value": 49 + }, + { + "date": "2025-10-30", + "value": 53 + }, + { + "date": "2025-11-04", + "value": 36 + }, + { + "date": "2025-11-10", + "value": 41 + }, + { + "date": "2025-11-16", + "value": 44 + }, + { + "date": "2025-11-22", + "value": 48 + }, + { + "date": "2025-11-28", + "value": 52 + }, + { + "date": "2025-12-05", + "value": 36 + }, + { + "date": "2025-12-11", + "value": 39 + }, + { + "date": "2025-12-17", + "value": 43 + }, + { + "date": "2025-12-23", + "value": 47 + }, + { + "date": "2025-12-29", + "value": 51 + }, + { + "date": "2026-01-06", + "value": 47 + }, + { + "date": "2026-01-12", + "value": 50 + }, + { + "date": "2026-01-18", + "value": 54 + }, + { + "date": "2026-01-24", + "value": 58 + }, + { + "date": "2026-01-30", + "value": 39 + }, + { + "date": "2026-02-04", + "value": 45 + }, + { + "date": "2026-02-10", + "value": 49 + }, + { + "date": "2026-02-16", + "value": 54 + }, + { + "date": "2026-02-22", + "value": 34 + }, + { + "date": "2026-02-28", + "value": 39 + }, + { + "date": "2026-03-05", + "value": 56 + }, + { + "date": "2026-03-11", + "value": 61 + }, + { + "date": "2026-03-17", + "value": 41 + }, + { + "date": "2026-03-23", + "value": 46 + }, + { + "date": "2026-03-29", + "value": 49 + }, + { + "date": "2026-04-06", + "value": 56 + }, + { + "date": "2026-04-12", + "value": 36 + }, + { + "date": "2026-04-18", + "value": 41 + }, + { + "date": "2026-04-24", + "value": 44 + }, + { + "date": "2026-04-30", + "value": 48 + }, + { + "date": "2026-05-04", + "value": 32 + }, + { + "date": "2026-05-10", + "value": 36 + }, + { + "date": "2026-05-16", + "value": 39 + }, + { + "date": "2026-05-22", + "value": 43 + }, + { + "date": "2026-05-28", + "value": 47 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 38.3, + "median": 35.0, + "p10": 21.4, + "p25": 26.5, + "p75": 48.5, + "p90": 56.6, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 53.8, + "median": 48.5, + "p10": 33.6, + "p25": 39.0, + "p75": 63.3, + "p90": 78.1, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 48.3, + "median": 48.0, + "p10": 29.6, + "p25": 36.5, + "p75": 60.0, + "p90": 67.2, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 55.0, + "median": 55.0, + "p10": 23.0, + "p25": 35.0, + "p75": 75.0, + "p90": 87.0, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 60.0, + "median": 45.0, + "p10": 28.4, + "p25": 38.0, + "p75": 65.0, + "p90": 104.0, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 44.5, + "median": 47.5, + "p10": 15.5, + "p25": 31.3, + "p75": 60.8, + "p90": 71.1, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 54.3, + "median": 50.0, + "p10": 32.4, + "p25": 39.0, + "p75": 67.5, + "p90": 78.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 69.4, + "median": 68.0, + "p10": 37.2, + "p25": 45.0, + "p75": 92.0, + "p90": 102.8, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 38.8, + "median": 38.5, + "p10": 24.5, + "p25": 31.3, + "p75": 46.0, + "p90": 53.2, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 46.6, + "median": 48.0, + "p10": 22.4, + "p25": 38.0, + "p75": 60.0, + "p90": 69.0, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 43.6, + "median": 42.0, + "p10": 36.0, + "p25": 39.0, + "p75": 49.0, + "p90": 52.0, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 50.0, + "median": 49.0, + "p10": 43.0, + "p25": 46.0, + "p75": 53.0, + "p90": 57.8, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 44.2, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 43.2, + "median": 43.0, + "p10": 37.2, + "p25": 39.0, + "p75": 47.0, + "p90": 49.4, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 49.6, + "median": 50.0, + "p10": 42.2, + "p25": 47.0, + "p75": 54.0, + "p90": 56.4, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 44.2, + "median": 45.0, + "p10": 36.0, + "p25": 39.0, + "p75": 49.0, + "p90": 52.0, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 50.6, + "median": 49.0, + "p10": 43.0, + "p25": 46.0, + "p75": 56.0, + "p90": 59.0, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 45.0, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 48.0, + "p90": 52.8, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 39.4, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 43.0, + "p90": 45.4, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "stats": { + "n": 83, + "mean": 48.3, + "median": 46.0, + "std": 19.8, + "min": 5, + "max": 130, + "p25": 38.5, + "p75": 54.5, + "p85": 61.0, + "p95": 87.7 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": { + "unit_price": 3.2, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 38, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_lowland_robusta.json new file mode 100644 index 00000000000..310c5fd7d6d --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_lowland_robusta.json @@ -0,0 +1,561 @@ +{ + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "durations": [ + 28, 45, 12, 62, 33, 78, 20, 55, 8, 42, 65, 38, 15, 72, 25, 48, 3, 85, 30, + 55, 22, 40, 98, 18, 39, 41, 45, 30, 34, 38, 41, 27, 30, 32, 38, 23, 27, 29, + 32, 28, 32, 34, 37, 40, 28, 31, 33, 36, 39, 36, 39, 41, 45, 30, 35, 38, 41, + 27, 30, 34, 38, 23, 27, 29, 43, 28, 32, 34, 37 + ], + "observations": [ + { + "date": "2022-05-02", + "value": 28 + }, + { + "date": "2022-05-10", + "value": 45 + }, + { + "date": "2022-05-18", + "value": 12 + }, + { + "date": "2022-05-25", + "value": 62 + }, + { + "date": "2023-02-06", + "value": 33 + }, + { + "date": "2023-02-14", + "value": 78 + }, + { + "date": "2023-02-22", + "value": 20 + }, + { + "date": "2023-02-28", + "value": 55 + }, + { + "date": "2023-09-05", + "value": 8 + }, + { + "date": "2023-09-15", + "value": 42 + }, + { + "date": "2023-09-25", + "value": 65 + }, + { + "date": "2024-04-03", + "value": 38 + }, + { + "date": "2024-04-10", + "value": 15 + }, + { + "date": "2024-04-17", + "value": 72 + }, + { + "date": "2024-04-24", + "value": 25 + }, + { + "date": "2024-10-02", + "value": 48 + }, + { + "date": "2024-10-09", + "value": 3 + }, + { + "date": "2024-10-16", + "value": 85 + }, + { + "date": "2024-10-23", + "value": 30 + }, + { + "date": "2024-10-30", + "value": 55 + }, + { + "date": "2025-04-07", + "value": 22 + }, + { + "date": "2025-04-14", + "value": 40 + }, + { + "date": "2025-04-21", + "value": 98 + }, + { + "date": "2025-04-28", + "value": 18 + }, + { + "date": "2025-09-04", + "value": 39 + }, + { + "date": "2025-09-10", + "value": 41 + }, + { + "date": "2025-09-16", + "value": 45 + }, + { + "date": "2025-09-22", + "value": 30 + }, + { + "date": "2025-09-28", + "value": 34 + }, + { + "date": "2025-10-05", + "value": 38 + }, + { + "date": "2025-10-11", + "value": 41 + }, + { + "date": "2025-10-17", + "value": 27 + }, + { + "date": "2025-10-23", + "value": 30 + }, + { + "date": "2025-10-29", + "value": 32 + }, + { + "date": "2025-11-06", + "value": 38 + }, + { + "date": "2025-11-12", + "value": 23 + }, + { + "date": "2025-11-18", + "value": 27 + }, + { + "date": "2025-11-24", + "value": 29 + }, + { + "date": "2025-11-30", + "value": 32 + }, + { + "date": "2025-12-04", + "value": 28 + }, + { + "date": "2025-12-10", + "value": 32 + }, + { + "date": "2025-12-16", + "value": 34 + }, + { + "date": "2025-12-22", + "value": 37 + }, + { + "date": "2025-12-28", + "value": 40 + }, + { + "date": "2026-01-05", + "value": 28 + }, + { + "date": "2026-01-11", + "value": 31 + }, + { + "date": "2026-01-17", + "value": 33 + }, + { + "date": "2026-01-23", + "value": 36 + }, + { + "date": "2026-01-29", + "value": 39 + }, + { + "date": "2026-02-06", + "value": 36 + }, + { + "date": "2026-02-12", + "value": 39 + }, + { + "date": "2026-02-18", + "value": 41 + }, + { + "date": "2026-02-24", + "value": 45 + }, + { + "date": "2026-02-30", + "value": 30 + }, + { + "date": "2026-03-04", + "value": 35 + }, + { + "date": "2026-03-10", + "value": 38 + }, + { + "date": "2026-03-16", + "value": 41 + }, + { + "date": "2026-03-22", + "value": 27 + }, + { + "date": "2026-03-28", + "value": 30 + }, + { + "date": "2026-04-05", + "value": 34 + }, + { + "date": "2026-04-11", + "value": 38 + }, + { + "date": "2026-04-17", + "value": 23 + }, + { + "date": "2026-04-23", + "value": 27 + }, + { + "date": "2026-04-29", + "value": 29 + }, + { + "date": "2026-05-06", + "value": 43 + }, + { + "date": "2026-05-12", + "value": 28 + }, + { + "date": "2026-05-18", + "value": 32 + }, + { + "date": "2026-05-24", + "value": 34 + }, + { + "date": "2026-05-30", + "value": 37 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 36.8, + "median": 36.5, + "p10": 16.8, + "p25": 24.0, + "p75": 49.3, + "p90": 56.9, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 46.5, + "median": 44.0, + "p10": 23.9, + "p25": 29.8, + "p75": 60.8, + "p90": 71.1, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 38.3, + "median": 42.0, + "p10": 14.8, + "p25": 25.0, + "p75": 53.5, + "p90": 60.4, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 37.5, + "median": 31.5, + "p10": 18.0, + "p25": 22.5, + "p75": 46.5, + "p90": 61.8, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 44.2, + "median": 48.0, + "p10": 13.8, + "p25": 30.0, + "p75": 55.0, + "p90": 73.0, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 44.5, + "median": 31.0, + "p10": 19.2, + "p25": 21.0, + "p75": 54.5, + "p90": 80.6, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 37.8, + "median": 39.0, + "p10": 31.6, + "p25": 34.0, + "p75": 41.0, + "p90": 43.4, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 33.6, + "median": 32.0, + "p10": 28.2, + "p25": 30.0, + "p75": 38.0, + "p90": 39.8, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 29.8, + "median": 29.0, + "p10": 24.6, + "p25": 27.0, + "p75": 32.0, + "p90": 35.6, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 34.2, + "median": 34.0, + "p10": 29.6, + "p25": 32.0, + "p75": 37.0, + "p90": 38.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 33.4, + "median": 33.0, + "p10": 29.2, + "p25": 31.0, + "p75": 36.0, + "p90": 37.8, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 38.2, + "median": 39.0, + "p10": 32.4, + "p25": 36.0, + "p75": 41.0, + "p90": 43.4, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 34.2, + "median": 35.0, + "p10": 28.2, + "p25": 30.0, + "p75": 38.0, + "p90": 39.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 30.2, + "median": 29.0, + "p10": 24.6, + "p25": 27.0, + "p75": 34.0, + "p90": 36.4, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 34.8, + "median": 34.0, + "p10": 29.6, + "p25": 32.0, + "p75": 37.0, + "p90": 40.6, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "stats": { + "n": 69, + "mean": 36.6, + "median": 34.0, + "std": 15.8, + "min": 3, + "max": 98, + "p25": 28.0, + "p75": 41.0, + "p85": 45.0, + "p95": 69.2 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "annotations": [], + "cost": { + "unit_price": 1.8, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 42, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_washed_bourbon.json new file mode 100644 index 00000000000..6d4f820e553 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/raw_dwell_washed_bourbon.json @@ -0,0 +1,565 @@ +{ + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "durations": [ + 40, 22, 68, 4, 55, 115, 30, 62, 18, 85, 35, 72, 10, 48, 95, 28, 52, 15, 78, + 42, 8, 65, 33, 100, 20, 41, 45, 48, 52, 34, 40, 44, 48, 30, 34, 50, 54, 36, + 41, 44, 50, 32, 36, 39, 43, 28, 32, 35, 38, 42, 39, 41, 45, 48, 52, 37, 40, + 44, 48, 30, 47, 50, 54, 36, 41, 46, 50, 32, 36, 39 + ], + "observations": [ + { + "date": "2022-06-05", + "value": 40 + }, + { + "date": "2022-06-15", + "value": 22 + }, + { + "date": "2022-06-25", + "value": 68 + }, + { + "date": "2023-03-08", + "value": 4 + }, + { + "date": "2023-03-15", + "value": 55 + }, + { + "date": "2023-03-22", + "value": 115 + }, + { + "date": "2023-03-29", + "value": 30 + }, + { + "date": "2023-11-06", + "value": 62 + }, + { + "date": "2023-11-13", + "value": 18 + }, + { + "date": "2023-11-20", + "value": 85 + }, + { + "date": "2024-06-03", + "value": 35 + }, + { + "date": "2024-06-10", + "value": 72 + }, + { + "date": "2024-06-17", + "value": 10 + }, + { + "date": "2024-06-24", + "value": 48 + }, + { + "date": "2024-06-30", + "value": 95 + }, + { + "date": "2025-01-07", + "value": 28 + }, + { + "date": "2025-01-14", + "value": 52 + }, + { + "date": "2025-01-21", + "value": 15 + }, + { + "date": "2025-01-28", + "value": 78 + }, + { + "date": "2025-08-04", + "value": 42 + }, + { + "date": "2025-08-08", + "value": 8 + }, + { + "date": "2025-08-12", + "value": 65 + }, + { + "date": "2025-08-16", + "value": 33 + }, + { + "date": "2025-08-20", + "value": 100 + }, + { + "date": "2025-08-24", + "value": 20 + }, + { + "date": "2025-09-06", + "value": 41 + }, + { + "date": "2025-09-12", + "value": 45 + }, + { + "date": "2025-09-18", + "value": 48 + }, + { + "date": "2025-09-24", + "value": 52 + }, + { + "date": "2025-09-30", + "value": 34 + }, + { + "date": "2025-10-04", + "value": 40 + }, + { + "date": "2025-10-10", + "value": 44 + }, + { + "date": "2025-10-16", + "value": 48 + }, + { + "date": "2025-10-22", + "value": 30 + }, + { + "date": "2025-10-28", + "value": 34 + }, + { + "date": "2025-11-05", + "value": 50 + }, + { + "date": "2025-11-11", + "value": 54 + }, + { + "date": "2025-11-17", + "value": 36 + }, + { + "date": "2025-11-23", + "value": 41 + }, + { + "date": "2025-11-29", + "value": 44 + }, + { + "date": "2025-12-06", + "value": 50 + }, + { + "date": "2025-12-12", + "value": 32 + }, + { + "date": "2025-12-18", + "value": 36 + }, + { + "date": "2025-12-24", + "value": 39 + }, + { + "date": "2025-12-30", + "value": 43 + }, + { + "date": "2026-01-04", + "value": 28 + }, + { + "date": "2026-01-10", + "value": 32 + }, + { + "date": "2026-01-16", + "value": 35 + }, + { + "date": "2026-01-22", + "value": 38 + }, + { + "date": "2026-01-28", + "value": 42 + }, + { + "date": "2026-02-05", + "value": 39 + }, + { + "date": "2026-02-11", + "value": 41 + }, + { + "date": "2026-02-17", + "value": 45 + }, + { + "date": "2026-02-23", + "value": 48 + }, + { + "date": "2026-02-29", + "value": 52 + }, + { + "date": "2026-03-06", + "value": 37 + }, + { + "date": "2026-03-12", + "value": 40 + }, + { + "date": "2026-03-18", + "value": 44 + }, + { + "date": "2026-03-24", + "value": 48 + }, + { + "date": "2026-03-30", + "value": 30 + }, + { + "date": "2026-04-04", + "value": 47 + }, + { + "date": "2026-04-10", + "value": 50 + }, + { + "date": "2026-04-16", + "value": 54 + }, + { + "date": "2026-04-22", + "value": 36 + }, + { + "date": "2026-04-28", + "value": 41 + }, + { + "date": "2026-05-05", + "value": 46 + }, + { + "date": "2026-05-11", + "value": 50 + }, + { + "date": "2026-05-17", + "value": 32 + }, + { + "date": "2026-05-23", + "value": 36 + }, + { + "date": "2026-05-29", + "value": 39 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 43.3, + "median": 40.0, + "p10": 25.6, + "p25": 31.0, + "p75": 54.0, + "p90": 62.4, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 51.0, + "median": 42.5, + "p10": 11.8, + "p25": 23.5, + "p75": 70.0, + "p90": 97.0, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 55.0, + "median": 62.0, + "p10": 26.8, + "p25": 40.0, + "p75": 73.5, + "p90": 80.4, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 52.0, + "median": 48.0, + "p10": 20.0, + "p25": 35.0, + "p75": 72.0, + "p90": 85.8, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 43.3, + "median": 40.0, + "p10": 18.9, + "p25": 24.8, + "p75": 58.5, + "p90": 70.2, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 44.7, + "median": 37.5, + "p10": 14.0, + "p25": 23.3, + "p75": 59.3, + "p90": 82.5, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 44.0, + "median": 45.0, + "p10": 36.8, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 39.2, + "median": 40.0, + "p10": 31.6, + "p25": 34.0, + "p75": 44.0, + "p90": 46.4, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 45.0, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 40.0, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 43.0, + "p90": 47.2, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 35.0, + "median": 35.0, + "p10": 29.6, + "p25": 32.0, + "p75": 38.0, + "p90": 40.4, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 45.0, + "median": 45.0, + "p10": 39.8, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 39.8, + "median": 40.0, + "p10": 32.8, + "p25": 37.0, + "p75": 44.0, + "p90": 46.4, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 45.6, + "median": 47.0, + "p10": 38.0, + "p25": 41.0, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 40.6, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 46.0, + "p90": 48.4, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "stats": { + "n": 70, + "mean": 43.9, + "median": 41.0, + "std": 19.1, + "min": 4, + "max": 115, + "p25": 34.3, + "p75": 50.0, + "p85": 54.0, + "p95": 81.9 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "annotations": [], + "cost": { + "unit_price": 5.5, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 25, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/transit_pla_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/transit_pla_hub1.json new file mode 100644 index 00000000000..72bddde415c --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/harbor-dark-roast/steps/transit_pla_hub1.json @@ -0,0 +1,436 @@ +{ + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "durations": [ + 28, 35, 22, 42, 30, 55, 25, 38, 15, 32, 28, 45, 30, 22, 36, 38, 39, 26, 36, + 23, 26, 27, 31, 33, 27, 29, 32, 26, 29, 31, 33, 36, 39, 33, 36, 23, 40, 27, + 31, 24, 27, 29 + ], + "observations": [ + { + "date": "2022-07-20", + "value": 28 + }, + { + "date": "2022-11-30", + "value": 35 + }, + { + "date": "2023-03-15", + "value": 22 + }, + { + "date": "2023-07-10", + "value": 42 + }, + { + "date": "2023-10-25", + "value": 30 + }, + { + "date": "2024-02-08", + "value": 55 + }, + { + "date": "2024-05-20", + "value": 25 + }, + { + "date": "2024-08-12", + "value": 38 + }, + { + "date": "2024-11-05", + "value": 15 + }, + { + "date": "2025-01-22", + "value": 32 + }, + { + "date": "2025-04-10", + "value": 28 + }, + { + "date": "2025-06-18", + "value": 45 + }, + { + "date": "2025-07-15", + "value": 30 + }, + { + "date": "2025-08-05", + "value": 22 + }, + { + "date": "2025-09-05", + "value": 36 + }, + { + "date": "2025-09-10", + "value": 38 + }, + { + "date": "2025-09-11", + "value": 39 + }, + { + "date": "2025-09-17", + "value": 26 + }, + { + "date": "2025-10-06", + "value": 36 + }, + { + "date": "2025-10-12", + "value": 23 + }, + { + "date": "2025-10-18", + "value": 26 + }, + { + "date": "2025-11-04", + "value": 27 + }, + { + "date": "2025-11-10", + "value": 31 + }, + { + "date": "2025-11-16", + "value": 33 + }, + { + "date": "2025-12-05", + "value": 27 + }, + { + "date": "2025-12-11", + "value": 29 + }, + { + "date": "2025-12-17", + "value": 32 + }, + { + "date": "2026-01-06", + "value": 26 + }, + { + "date": "2026-01-12", + "value": 29 + }, + { + "date": "2026-01-18", + "value": 31 + }, + { + "date": "2026-02-04", + "value": 33 + }, + { + "date": "2026-02-10", + "value": 36 + }, + { + "date": "2026-02-16", + "value": 39 + }, + { + "date": "2026-03-05", + "value": 33 + }, + { + "date": "2026-03-11", + "value": 36 + }, + { + "date": "2026-03-17", + "value": 23 + }, + { + "date": "2026-04-06", + "value": 40 + }, + { + "date": "2026-04-12", + "value": 27 + }, + { + "date": "2026-04-18", + "value": 31 + }, + { + "date": "2026-05-04", + "value": 24 + }, + { + "date": "2026-05-10", + "value": 27 + }, + { + "date": "2026-05-16", + "value": 29 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-08", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 32.0, + "median": 32.0, + "p10": 32.0, + "p25": 32.0, + "p75": 32.0, + "p90": 32.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 45.0, + "median": 45.0, + "p10": 45.0, + "p25": 45.0, + "p75": 45.0, + "p90": 45.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 34.8, + "median": 37.0, + "p10": 29.0, + "p25": 33.5, + "p75": 38.3, + "p90": 38.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 28.3, + "median": 26.0, + "p10": 23.6, + "p25": 24.5, + "p75": 31.0, + "p90": 34.0, + "n": 3 + }, + { + "month": "2025-11", + "mean": 30.3, + "median": 31.0, + "p10": 27.8, + "p25": 29.0, + "p75": 32.0, + "p90": 32.6, + "n": 3 + }, + { + "month": "2025-12", + "mean": 29.3, + "median": 29.0, + "p10": 27.4, + "p25": 28.0, + "p75": 30.5, + "p90": 31.4, + "n": 3 + }, + { + "month": "2026-01", + "mean": 28.7, + "median": 29.0, + "p10": 26.6, + "p25": 27.5, + "p75": 30.0, + "p90": 30.6, + "n": 3 + }, + { + "month": "2026-02", + "mean": 36.0, + "median": 36.0, + "p10": 33.6, + "p25": 34.5, + "p75": 37.5, + "p90": 38.4, + "n": 3 + }, + { + "month": "2026-03", + "mean": 30.7, + "median": 33.0, + "p10": 25.0, + "p25": 28.0, + "p75": 34.5, + "p90": 35.4, + "n": 3 + }, + { + "month": "2026-04", + "mean": 32.7, + "median": 31.0, + "p10": 27.8, + "p25": 29.0, + "p75": 35.5, + "p90": 38.2, + "n": 3 + }, + { + "month": "2026-05", + "mean": 26.7, + "median": 27.0, + "p10": 24.6, + "p25": 25.5, + "p75": 28.0, + "p90": 28.6, + "n": 3 + } + ], + "stats": { + "n": 42, + "mean": 31.3, + "median": 30.5, + "std": 7.1, + "min": 15, + "max": 55, + "p25": 27.0, + "p75": 36.0, + "p85": 38.0, + "p95": 41.9 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 15, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/manifest.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/manifest.json new file mode 100644 index 00000000000..e7ab7e61aa8 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/manifest.json @@ -0,0 +1,72 @@ +{ + "datasetVersion": "2026-06-17.1", + "products": [ + "harbor-dark-roast", + "summit-medium-roast", + "riverside-decaf", + "meadow-espresso" + ], + "sites": ["harbor-roastery"], + "steps": { + "harbor-dark-roast": [ + "dest_dwell_hub1", + "intermed_dwell_green_blend", + "post_qa_ship_pla", + "procurement_highland_arabica", + "procurement_lowland_robusta", + "procurement_washed_bourbon", + "prod_duration_green_blend", + "prod_duration_harbor_dark_roast", + "prod_to_qa_pla", + "raw_dwell_highland_arabica", + "raw_dwell_lowland_robusta", + "raw_dwell_washed_bourbon", + "transit_pla_hub1" + ], + "summit-medium-roast": [ + "dest_dwell_hub1", + "intermed_dwell_green_blend", + "post_qa_ship_pla", + "procurement_highland_arabica", + "procurement_lowland_robusta", + "procurement_washed_bourbon", + "prod_duration_green_blend", + "prod_duration_harbor_dark_roast", + "prod_to_qa_pla", + "raw_dwell_highland_arabica", + "raw_dwell_lowland_robusta", + "raw_dwell_washed_bourbon", + "transit_pla_hub1" + ], + "riverside-decaf": [ + "dest_dwell_hub1", + "intermed_dwell_green_blend", + "post_qa_ship_pla", + "procurement_highland_arabica", + "procurement_lowland_robusta", + "procurement_washed_bourbon", + "prod_duration_green_blend", + "prod_duration_harbor_dark_roast", + "prod_to_qa_pla", + "raw_dwell_highland_arabica", + "raw_dwell_lowland_robusta", + "raw_dwell_washed_bourbon", + "transit_pla_hub1" + ], + "meadow-espresso": [ + "dest_dwell_hub1", + "intermed_dwell_green_blend", + "post_qa_ship_pla", + "procurement_highland_arabica", + "procurement_lowland_robusta", + "procurement_washed_bourbon", + "prod_duration_green_blend", + "prod_duration_harbor_dark_roast", + "prod_to_qa_pla", + "raw_dwell_highland_arabica", + "raw_dwell_lowland_robusta", + "raw_dwell_washed_bourbon", + "transit_pla_hub1" + ] + } +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/graph.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/graph.json new file mode 100644 index 00000000000..1340390934c --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/graph.json @@ -0,0 +1,16588 @@ +{ + "product_id": "meadow-espresso", + "product_name": "Meadow Espresso", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 54.3, + "median": 54.0, + "std": 18.0, + "min": 10.8, + "max": 141.8, + "p25": 47.2, + "p75": 60.8, + "p85": 64.8, + "p95": 75.3 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 74.2 + }, + { + "date": "2022-06-10", + "value": 56.7 + }, + { + "date": "2022-09-22", + "value": 10.8 + }, + { + "date": "2022-12-05", + "value": 85.1 + }, + { + "date": "2023-02-14", + "value": 51.3 + }, + { + "date": "2023-05-30", + "value": 29.7 + }, + { + "date": "2023-08-17", + "value": 95.9 + }, + { + "date": "2023-11-02", + "value": 40.5 + }, + { + "date": "2024-01-25", + "value": 60.8 + }, + { + "date": "2024-04-11", + "value": 24.3 + }, + { + "date": "2024-07-09", + "value": 141.8 + }, + { + "date": "2024-10-03", + "value": 47.2 + }, + { + "date": "2025-01-20", + "value": 16.2 + }, + { + "date": "2025-04-08", + "value": 64.8 + }, + { + "date": "2025-09-05", + "value": 52.7 + }, + { + "date": "2025-09-11", + "value": 55.4 + }, + { + "date": "2025-09-17", + "value": 59.4 + }, + { + "date": "2025-09-23", + "value": 64.8 + }, + { + "date": "2025-09-29", + "value": 68.9 + }, + { + "date": "2025-10-06", + "value": 50.0 + }, + { + "date": "2025-10-12", + "value": 54.0 + }, + { + "date": "2025-10-18", + "value": 59.4 + }, + { + "date": "2025-10-24", + "value": 63.5 + }, + { + "date": "2025-10-30", + "value": 41.9 + }, + { + "date": "2025-11-04", + "value": 48.6 + }, + { + "date": "2025-11-10", + "value": 54.0 + }, + { + "date": "2025-11-16", + "value": 58.1 + }, + { + "date": "2025-11-22", + "value": 36.5 + }, + { + "date": "2025-11-28", + "value": 41.9 + }, + { + "date": "2025-12-05", + "value": 62.1 + }, + { + "date": "2025-12-11", + "value": 66.2 + }, + { + "date": "2025-12-17", + "value": 44.6 + }, + { + "date": "2025-12-23", + "value": 50.0 + }, + { + "date": "2025-12-29", + "value": 52.7 + }, + { + "date": "2026-01-06", + "value": 60.8 + }, + { + "date": "2026-01-12", + "value": 39.2 + }, + { + "date": "2026-01-18", + "value": 44.6 + }, + { + "date": "2026-01-24", + "value": 47.2 + }, + { + "date": "2026-01-30", + "value": 51.3 + }, + { + "date": "2026-02-04", + "value": 47.2 + }, + { + "date": "2026-02-10", + "value": 52.7 + }, + { + "date": "2026-02-16", + "value": 55.4 + }, + { + "date": "2026-02-22", + "value": 59.4 + }, + { + "date": "2026-02-28", + "value": 64.8 + }, + { + "date": "2026-03-05", + "value": 47.2 + }, + { + "date": "2026-03-11", + "value": 50.0 + }, + { + "date": "2026-03-17", + "value": 54.0 + }, + { + "date": "2026-03-23", + "value": 59.4 + }, + { + "date": "2026-03-29", + "value": 63.5 + }, + { + "date": "2026-04-06", + "value": 44.6 + }, + { + "date": "2026-04-12", + "value": 48.6 + }, + { + "date": "2026-04-18", + "value": 54.0 + }, + { + "date": "2026-04-24", + "value": 58.1 + }, + { + "date": "2026-04-30", + "value": 36.5 + }, + { + "date": "2026-05-04", + "value": 56.7 + }, + { + "date": "2026-05-10", + "value": 62.1 + }, + { + "date": "2026-05-16", + "value": 66.2 + }, + { + "date": "2026-05-22", + "value": 44.6 + }, + { + "date": "2026-05-28", + "value": 50.0 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2022-06", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1 + }, + { + "month": "2022-09", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2022-12", + "mean": 85.1, + "median": 85.1, + "p10": 85.1, + "p25": 85.1, + "p75": 85.1, + "p90": 85.1, + "n": 1 + }, + { + "month": "2023-02", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2023-05", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2023-08", + "mean": 95.9, + "median": 95.9, + "p10": 95.9, + "p25": 95.9, + "p75": 95.9, + "p90": 95.9, + "n": 1 + }, + { + "month": "2023-11", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 60.8, + "median": 60.8, + "p10": 60.8, + "p25": 60.8, + "p75": 60.8, + "p90": 60.8, + "n": 1 + }, + { + "month": "2024-04", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 141.8, + "median": 141.8, + "p10": 141.8, + "p25": 141.8, + "p75": 141.8, + "p90": 141.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2025-09", + "mean": 60.2, + "median": 59.4, + "p10": 53.7, + "p25": 55.4, + "p75": 64.8, + "p90": 67.2, + "n": 5 + }, + { + "month": "2025-10", + "mean": 53.7, + "median": 54.0, + "p10": 45.1, + "p25": 50.0, + "p75": 59.4, + "p90": 61.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 47.8, + "median": 48.6, + "p10": 38.6, + "p25": 41.9, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2025-12", + "mean": 55.1, + "median": 52.7, + "p10": 46.7, + "p25": 50.0, + "p75": 62.1, + "p90": 64.5, + "n": 5 + }, + { + "month": "2026-01", + "mean": 48.6, + "median": 47.2, + "p10": 41.3, + "p25": 44.6, + "p75": 51.3, + "p90": 57.0, + "n": 5 + }, + { + "month": "2026-02", + "mean": 55.9, + "median": 55.4, + "p10": 49.4, + "p25": 52.7, + "p75": 59.4, + "p90": 62.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 54.8, + "median": 54.0, + "p10": 48.3, + "p25": 50.0, + "p75": 59.4, + "p90": 61.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 48.3, + "median": 48.6, + "p10": 39.7, + "p25": 44.6, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-05", + "mean": 55.9, + "median": 56.7, + "p10": 46.7, + "p25": 50.0, + "p75": 62.1, + "p90": 64.5, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 45.1, + "median": 44.6, + "std": 15.4, + "min": 6.8, + "max": 110.7, + "p25": 37.8, + "p75": 51.3, + "p85": 54.9, + "p95": 69.7 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 43.2 + }, + { + "date": "2022-04-19", + "value": 64.8 + }, + { + "date": "2022-07-11", + "value": 6.8 + }, + { + "date": "2022-09-28", + "value": 90.5 + }, + { + "date": "2022-12-15", + "value": 33.8 + }, + { + "date": "2023-03-07", + "value": 55.4 + }, + { + "date": "2023-05-22", + "value": 20.2 + }, + { + "date": "2023-08-09", + "value": 110.7 + }, + { + "date": "2023-10-30", + "value": 51.3 + }, + { + "date": "2024-01-16", + "value": 27.0 + }, + { + "date": "2024-03-25", + "value": 70.2 + }, + { + "date": "2024-06-12", + "value": 13.5 + }, + { + "date": "2024-08-28", + "value": 59.4 + }, + { + "date": "2024-11-14", + "value": 37.8 + }, + { + "date": "2025-01-06", + "value": 47.2 + }, + { + "date": "2025-03-18", + "value": 24.3 + }, + { + "date": "2025-05-29", + "value": 74.2 + }, + { + "date": "2025-08-12", + "value": 35.1 + }, + { + "date": "2025-09-04", + "value": 35.1 + }, + { + "date": "2025-09-10", + "value": 39.2 + }, + { + "date": "2025-09-16", + "value": 41.9 + }, + { + "date": "2025-09-22", + "value": 45.9 + }, + { + "date": "2025-09-28", + "value": 50.0 + }, + { + "date": "2025-10-05", + "value": 35.1 + }, + { + "date": "2025-10-11", + "value": 37.8 + }, + { + "date": "2025-10-17", + "value": 41.9 + }, + { + "date": "2025-10-23", + "value": 44.6 + }, + { + "date": "2025-10-29", + "value": 48.6 + }, + { + "date": "2025-11-06", + "value": 44.6 + }, + { + "date": "2025-11-12", + "value": 48.6 + }, + { + "date": "2025-11-18", + "value": 51.3 + }, + { + "date": "2025-11-24", + "value": 56.7 + }, + { + "date": "2025-11-30", + "value": 37.8 + }, + { + "date": "2025-12-04", + "value": 43.2 + }, + { + "date": "2025-12-10", + "value": 47.2 + }, + { + "date": "2025-12-16", + "value": 51.3 + }, + { + "date": "2025-12-22", + "value": 32.4 + }, + { + "date": "2025-12-28", + "value": 37.8 + }, + { + "date": "2026-01-05", + "value": 54.0 + }, + { + "date": "2026-01-11", + "value": 58.1 + }, + { + "date": "2026-01-17", + "value": 39.2 + }, + { + "date": "2026-01-23", + "value": 44.6 + }, + { + "date": "2026-01-29", + "value": 47.2 + }, + { + "date": "2026-02-06", + "value": 54.0 + }, + { + "date": "2026-02-12", + "value": 35.1 + }, + { + "date": "2026-02-18", + "value": 39.2 + }, + { + "date": "2026-02-24", + "value": 41.9 + }, + { + "date": "2026-02-30", + "value": 45.9 + }, + { + "date": "2026-03-04", + "value": 29.7 + }, + { + "date": "2026-03-10", + "value": 35.1 + }, + { + "date": "2026-03-16", + "value": 37.8 + }, + { + "date": "2026-03-22", + "value": 41.9 + }, + { + "date": "2026-03-28", + "value": 44.6 + }, + { + "date": "2026-04-05", + "value": 41.9 + }, + { + "date": "2026-04-11", + "value": 44.6 + }, + { + "date": "2026-04-17", + "value": 48.6 + }, + { + "date": "2026-04-23", + "value": 51.3 + }, + { + "date": "2026-04-29", + "value": 56.7 + }, + { + "date": "2026-05-06", + "value": 40.5 + }, + { + "date": "2026-05-12", + "value": 43.2 + }, + { + "date": "2026-05-18", + "value": 47.2 + }, + { + "date": "2026-05-24", + "value": 51.3 + }, + { + "date": "2026-05-30", + "value": 32.4 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 43.2, + "median": 43.2, + "p10": 43.2, + "p25": 43.2, + "p75": 43.2, + "p90": 43.2, + "n": 1 + }, + { + "month": "2022-04", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2022-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-09", + "mean": 90.5, + "median": 90.5, + "p10": 90.5, + "p25": 90.5, + "p75": 90.5, + "p90": 90.5, + "n": 1 + }, + { + "month": "2022-12", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2023-03", + "mean": 55.4, + "median": 55.4, + "p10": 55.4, + "p25": 55.4, + "p75": 55.4, + "p90": 55.4, + "n": 1 + }, + { + "month": "2023-05", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2023-08", + "mean": 110.7, + "median": 110.7, + "p10": 110.7, + "p25": 110.7, + "p75": 110.7, + "p90": 110.7, + "n": 1 + }, + { + "month": "2023-10", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-01", + "mean": 27.0, + "median": 27.0, + "p10": 27.0, + "p25": 27.0, + "p75": 27.0, + "p90": 27.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 70.2, + "median": 70.2, + "p10": 70.2, + "p25": 70.2, + "p75": 70.2, + "p90": 70.2, + "n": 1 + }, + { + "month": "2024-06", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 59.4, + "median": 59.4, + "p10": 59.4, + "p25": 59.4, + "p75": 59.4, + "p90": 59.4, + "n": 1 + }, + { + "month": "2024-11", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-01", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2025-03", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2025-05", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 35.1, + "median": 35.1, + "p10": 35.1, + "p25": 35.1, + "p75": 35.1, + "p90": 35.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 42.4, + "median": 41.9, + "p10": 36.7, + "p25": 39.2, + "p75": 45.9, + "p90": 48.3, + "n": 5 + }, + { + "month": "2025-10", + "mean": 41.6, + "median": 41.9, + "p10": 36.2, + "p25": 37.8, + "p75": 44.6, + "p90": 47.0, + "n": 5 + }, + { + "month": "2025-11", + "mean": 47.8, + "median": 48.6, + "p10": 40.5, + "p25": 44.6, + "p75": 51.3, + "p90": 54.5, + "n": 5 + }, + { + "month": "2025-12", + "mean": 42.4, + "median": 43.2, + "p10": 34.6, + "p25": 37.8, + "p75": 47.2, + "p90": 49.7, + "n": 5 + }, + { + "month": "2026-01", + "mean": 48.6, + "median": 47.2, + "p10": 41.3, + "p25": 44.6, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-02", + "mean": 43.2, + "median": 41.9, + "p10": 36.7, + "p25": 39.2, + "p75": 45.9, + "p90": 50.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 37.8, + "median": 37.8, + "p10": 31.9, + "p25": 35.1, + "p75": 41.9, + "p90": 43.5, + "n": 5 + }, + { + "month": "2026-04", + "mean": 48.6, + "median": 48.6, + "p10": 42.9, + "p25": 44.6, + "p75": 51.3, + "p90": 54.5, + "n": 5 + }, + { + "month": "2026-05", + "mean": 42.9, + "median": 43.2, + "p10": 35.6, + "p25": 40.5, + "p75": 47.2, + "p90": 49.7, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 35.2, + "median": 33.8, + "std": 10.8, + "min": 9.5, + "max": 83.7, + "p25": 30.4, + "p75": 39.2, + "p85": 40.5, + "p95": 49.3 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 47.2 + }, + { + "date": "2022-10-18", + "value": 21.6 + }, + { + "date": "2023-01-24", + "value": 83.7 + }, + { + "date": "2023-06-15", + "value": 9.5 + }, + { + "date": "2023-09-28", + "value": 54.0 + }, + { + "date": "2024-02-12", + "value": 33.8 + }, + { + "date": "2024-05-07", + "value": 64.8 + }, + { + "date": "2024-09-19", + "value": 16.2 + }, + { + "date": "2025-02-04", + "value": 40.5 + }, + { + "date": "2025-06-10", + "value": 18.9 + }, + { + "date": "2025-09-06", + "value": 40.5 + }, + { + "date": "2025-09-12", + "value": 25.7 + }, + { + "date": "2025-09-18", + "value": 29.7 + }, + { + "date": "2025-09-24", + "value": 31.1 + }, + { + "date": "2025-09-30", + "value": 33.8 + }, + { + "date": "2025-10-04", + "value": 31.1 + }, + { + "date": "2025-10-10", + "value": 33.8 + }, + { + "date": "2025-10-16", + "value": 36.5 + }, + { + "date": "2025-10-22", + "value": 39.2 + }, + { + "date": "2025-10-28", + "value": 41.9 + }, + { + "date": "2025-11-05", + "value": 31.1 + }, + { + "date": "2025-11-11", + "value": 33.8 + }, + { + "date": "2025-11-17", + "value": 36.5 + }, + { + "date": "2025-11-23", + "value": 39.2 + }, + { + "date": "2025-11-29", + "value": 41.9 + }, + { + "date": "2025-12-06", + "value": 29.7 + }, + { + "date": "2025-12-12", + "value": 32.4 + }, + { + "date": "2025-12-18", + "value": 35.1 + }, + { + "date": "2025-12-24", + "value": 37.8 + }, + { + "date": "2025-12-30", + "value": 24.3 + }, + { + "date": "2026-01-04", + "value": 37.8 + }, + { + "date": "2026-01-10", + "value": 40.5 + }, + { + "date": "2026-01-16", + "value": 43.2 + }, + { + "date": "2026-01-22", + "value": 29.7 + }, + { + "date": "2026-01-28", + "value": 32.4 + }, + { + "date": "2026-02-05", + "value": 36.5 + }, + { + "date": "2026-02-11", + "value": 40.5 + }, + { + "date": "2026-02-17", + "value": 25.7 + }, + { + "date": "2026-02-23", + "value": 29.7 + }, + { + "date": "2026-02-29", + "value": 31.1 + }, + { + "date": "2026-03-06", + "value": 45.9 + }, + { + "date": "2026-03-12", + "value": 31.1 + }, + { + "date": "2026-03-18", + "value": 33.8 + }, + { + "date": "2026-03-24", + "value": 36.5 + }, + { + "date": "2026-03-30", + "value": 39.2 + }, + { + "date": "2026-04-04", + "value": 27.0 + }, + { + "date": "2026-04-10", + "value": 31.1 + }, + { + "date": "2026-04-16", + "value": 33.8 + }, + { + "date": "2026-04-22", + "value": 36.5 + }, + { + "date": "2026-04-28", + "value": 39.2 + }, + { + "date": "2026-05-05", + "value": 27.0 + }, + { + "date": "2026-05-11", + "value": 29.7 + }, + { + "date": "2026-05-17", + "value": 32.4 + }, + { + "date": "2026-05-23", + "value": 35.1 + }, + { + "date": "2026-05-29", + "value": 37.8 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 21.6, + "median": 21.6, + "p10": 21.6, + "p25": 21.6, + "p75": 21.6, + "p90": 21.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 83.7, + "median": 83.7, + "p10": 83.7, + "p25": 83.7, + "p75": 83.7, + "p90": 83.7, + "n": 1 + }, + { + "month": "2023-06", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 54.0, + "median": 54.0, + "p10": 54.0, + "p25": 54.0, + "p75": 54.0, + "p90": 54.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-05", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2025-02", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2025-06", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 32.1, + "median": 31.1, + "p10": 27.3, + "p25": 29.7, + "p75": 33.8, + "p90": 37.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 36.5, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 36.5, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 31.9, + "median": 32.4, + "p10": 26.5, + "p25": 29.7, + "p75": 35.1, + "p90": 36.7, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.7, + "median": 37.8, + "p10": 30.8, + "p25": 32.4, + "p75": 40.5, + "p90": 42.1, + "n": 5 + }, + { + "month": "2026-02", + "mean": 32.7, + "median": 31.1, + "p10": 27.3, + "p25": 29.7, + "p75": 36.5, + "p90": 38.9, + "n": 5 + }, + { + "month": "2026-03", + "mean": 37.3, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 43.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 33.5, + "median": 33.8, + "p10": 28.6, + "p25": 31.1, + "p75": 36.5, + "p90": 38.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 32.4, + "median": 32.4, + "p10": 28.1, + "p25": 29.7, + "p75": 35.1, + "p90": 36.7, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 65.2, + "median": 62.1, + "std": 26.7, + "min": 6.8, + "max": 175.5, + "p25": 52.0, + "p75": 73.6, + "p85": 82.4, + "p95": 118.4 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 4.32, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 47.2 + }, + { + "date": "2022-04-15", + "value": 83.7 + }, + { + "date": "2022-04-28", + "value": 24.3 + }, + { + "date": "2022-08-05", + "value": 118.8 + }, + { + "date": "2022-08-12", + "value": 56.7 + }, + { + "date": "2022-08-20", + "value": 74.2 + }, + { + "date": "2022-08-28", + "value": 40.5 + }, + { + "date": "2023-01-10", + "value": 97.2 + }, + { + "date": "2023-01-22", + "value": 33.8 + }, + { + "date": "2023-01-30", + "value": 64.8 + }, + { + "date": "2023-06-05", + "value": 20.2 + }, + { + "date": "2023-06-18", + "value": 128.2 + }, + { + "date": "2023-10-03", + "value": 175.5 + }, + { + "date": "2023-10-10", + "value": 60.8 + }, + { + "date": "2023-10-18", + "value": 51.3 + }, + { + "date": "2023-10-25", + "value": 87.8 + }, + { + "date": "2023-10-30", + "value": 29.7 + }, + { + "date": "2024-03-05", + "value": 105.3 + }, + { + "date": "2024-03-12", + "value": 6.8 + }, + { + "date": "2024-03-20", + "value": 74.2 + }, + { + "date": "2024-03-28", + "value": 54.0 + }, + { + "date": "2024-07-08", + "value": 37.8 + }, + { + "date": "2024-07-15", + "value": 114.8 + }, + { + "date": "2024-07-22", + "value": 67.5 + }, + { + "date": "2024-11-04", + "value": 148.5 + }, + { + "date": "2024-11-11", + "value": 43.2 + }, + { + "date": "2024-11-18", + "value": 91.8 + }, + { + "date": "2024-11-25", + "value": 60.8 + }, + { + "date": "2024-11-30", + "value": 124.2 + }, + { + "date": "2025-03-03", + "value": 27.0 + }, + { + "date": "2025-03-10", + "value": 78.3 + }, + { + "date": "2025-03-17", + "value": 47.2 + }, + { + "date": "2025-03-24", + "value": 56.7 + }, + { + "date": "2025-07-02", + "value": 101.2 + }, + { + "date": "2025-07-09", + "value": 16.2 + }, + { + "date": "2025-07-16", + "value": 64.8 + }, + { + "date": "2025-07-23", + "value": 81.0 + }, + { + "date": "2025-07-30", + "value": 51.3 + }, + { + "date": "2025-09-05", + "value": 66.2 + }, + { + "date": "2025-09-11", + "value": 72.9 + }, + { + "date": "2025-09-17", + "value": 45.9 + }, + { + "date": "2025-09-23", + "value": 52.7 + }, + { + "date": "2025-09-29", + "value": 56.7 + }, + { + "date": "2025-10-06", + "value": 82.4 + }, + { + "date": "2025-10-12", + "value": 55.4 + }, + { + "date": "2025-10-18", + "value": 62.1 + }, + { + "date": "2025-10-24", + "value": 66.2 + }, + { + "date": "2025-10-30", + "value": 71.6 + }, + { + "date": "2025-11-04", + "value": 48.6 + }, + { + "date": "2025-11-10", + "value": 55.4 + }, + { + "date": "2025-11-16", + "value": 59.4 + }, + { + "date": "2025-11-22", + "value": 64.8 + }, + { + "date": "2025-11-28", + "value": 70.2 + }, + { + "date": "2025-12-05", + "value": 48.6 + }, + { + "date": "2025-12-11", + "value": 52.7 + }, + { + "date": "2025-12-17", + "value": 58.1 + }, + { + "date": "2025-12-23", + "value": 63.5 + }, + { + "date": "2025-12-29", + "value": 68.9 + }, + { + "date": "2026-01-06", + "value": 63.5 + }, + { + "date": "2026-01-12", + "value": 67.5 + }, + { + "date": "2026-01-18", + "value": 72.9 + }, + { + "date": "2026-01-24", + "value": 78.3 + }, + { + "date": "2026-01-30", + "value": 52.7 + }, + { + "date": "2026-02-04", + "value": 60.8 + }, + { + "date": "2026-02-10", + "value": 66.2 + }, + { + "date": "2026-02-16", + "value": 72.9 + }, + { + "date": "2026-02-22", + "value": 45.9 + }, + { + "date": "2026-02-28", + "value": 52.7 + }, + { + "date": "2026-03-05", + "value": 75.6 + }, + { + "date": "2026-03-11", + "value": 82.4 + }, + { + "date": "2026-03-17", + "value": 55.4 + }, + { + "date": "2026-03-23", + "value": 62.1 + }, + { + "date": "2026-03-29", + "value": 66.2 + }, + { + "date": "2026-04-06", + "value": 75.6 + }, + { + "date": "2026-04-12", + "value": 48.6 + }, + { + "date": "2026-04-18", + "value": 55.4 + }, + { + "date": "2026-04-24", + "value": 59.4 + }, + { + "date": "2026-04-30", + "value": 64.8 + }, + { + "date": "2026-05-04", + "value": 43.2 + }, + { + "date": "2026-05-10", + "value": 48.6 + }, + { + "date": "2026-05-16", + "value": 52.7 + }, + { + "date": "2026-05-22", + "value": 58.1 + }, + { + "date": "2026-05-28", + "value": 63.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 51.7, + "median": 47.2, + "p10": 28.9, + "p25": 35.8, + "p75": 65.5, + "p90": 76.4, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 72.6, + "median": 65.5, + "p10": 45.4, + "p25": 52.7, + "p75": 85.5, + "p90": 105.4, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 65.2, + "median": 64.8, + "p10": 40.0, + "p25": 49.3, + "p75": 81.0, + "p90": 90.7, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 74.2, + "median": 74.2, + "p10": 31.1, + "p25": 47.2, + "p75": 101.2, + "p90": 117.5, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 81.0, + "median": 60.8, + "p10": 38.3, + "p25": 51.3, + "p75": 87.8, + "p90": 140.4, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 60.1, + "median": 64.1, + "p10": 20.9, + "p25": 42.3, + "p75": 82.1, + "p90": 96.0, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 73.3, + "median": 67.5, + "p10": 43.7, + "p25": 52.7, + "p75": 91.1, + "p90": 105.3, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 93.7, + "median": 91.8, + "p10": 50.2, + "p25": 60.8, + "p75": 124.2, + "p90": 138.8, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 52.4, + "median": 52.0, + "p10": 33.1, + "p25": 42.3, + "p75": 62.1, + "p90": 71.8, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 62.9, + "median": 64.8, + "p10": 30.2, + "p25": 51.3, + "p75": 81.0, + "p90": 93.2, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 58.9, + "median": 56.7, + "p10": 48.6, + "p25": 52.7, + "p75": 66.2, + "p90": 70.2, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 67.5, + "median": 66.2, + "p10": 58.1, + "p25": 62.1, + "p75": 71.6, + "p90": 78.0, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 59.7, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 58.3, + "median": 58.1, + "p10": 50.2, + "p25": 52.7, + "p75": 63.5, + "p90": 66.7, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 67.0, + "median": 67.5, + "p10": 57.0, + "p25": 63.5, + "p75": 72.9, + "p90": 76.1, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 59.7, + "median": 60.8, + "p10": 48.6, + "p25": 52.7, + "p75": 66.2, + "p90": 70.2, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 68.3, + "median": 66.2, + "p10": 58.1, + "p25": 62.1, + "p75": 75.6, + "p90": 79.7, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 60.8, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 64.8, + "p90": 71.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 53.2, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 58.1, + "p90": 61.3, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 49.4, + "median": 45.9, + "std": 21.3, + "min": 4.1, + "max": 132.3, + "p25": 37.8, + "p75": 55.4, + "p85": 60.8, + "p95": 93.4 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 2.43, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 37.8 + }, + { + "date": "2022-05-10", + "value": 60.8 + }, + { + "date": "2022-05-18", + "value": 16.2 + }, + { + "date": "2022-05-25", + "value": 83.7 + }, + { + "date": "2023-02-06", + "value": 44.6 + }, + { + "date": "2023-02-14", + "value": 105.3 + }, + { + "date": "2023-02-22", + "value": 27.0 + }, + { + "date": "2023-02-28", + "value": 74.2 + }, + { + "date": "2023-09-05", + "value": 10.8 + }, + { + "date": "2023-09-15", + "value": 56.7 + }, + { + "date": "2023-09-25", + "value": 87.8 + }, + { + "date": "2024-04-03", + "value": 51.3 + }, + { + "date": "2024-04-10", + "value": 20.2 + }, + { + "date": "2024-04-17", + "value": 97.2 + }, + { + "date": "2024-04-24", + "value": 33.8 + }, + { + "date": "2024-10-02", + "value": 64.8 + }, + { + "date": "2024-10-09", + "value": 4.1 + }, + { + "date": "2024-10-16", + "value": 114.8 + }, + { + "date": "2024-10-23", + "value": 40.5 + }, + { + "date": "2024-10-30", + "value": 74.2 + }, + { + "date": "2025-04-07", + "value": 29.7 + }, + { + "date": "2025-04-14", + "value": 54.0 + }, + { + "date": "2025-04-21", + "value": 132.3 + }, + { + "date": "2025-04-28", + "value": 24.3 + }, + { + "date": "2025-09-04", + "value": 52.7 + }, + { + "date": "2025-09-10", + "value": 55.4 + }, + { + "date": "2025-09-16", + "value": 60.8 + }, + { + "date": "2025-09-22", + "value": 40.5 + }, + { + "date": "2025-09-28", + "value": 45.9 + }, + { + "date": "2025-10-05", + "value": 51.3 + }, + { + "date": "2025-10-11", + "value": 55.4 + }, + { + "date": "2025-10-17", + "value": 36.5 + }, + { + "date": "2025-10-23", + "value": 40.5 + }, + { + "date": "2025-10-29", + "value": 43.2 + }, + { + "date": "2025-11-06", + "value": 51.3 + }, + { + "date": "2025-11-12", + "value": 31.1 + }, + { + "date": "2025-11-18", + "value": 36.5 + }, + { + "date": "2025-11-24", + "value": 39.2 + }, + { + "date": "2025-11-30", + "value": 43.2 + }, + { + "date": "2025-12-04", + "value": 37.8 + }, + { + "date": "2025-12-10", + "value": 43.2 + }, + { + "date": "2025-12-16", + "value": 45.9 + }, + { + "date": "2025-12-22", + "value": 50.0 + }, + { + "date": "2025-12-28", + "value": 54.0 + }, + { + "date": "2026-01-05", + "value": 37.8 + }, + { + "date": "2026-01-11", + "value": 41.9 + }, + { + "date": "2026-01-17", + "value": 44.6 + }, + { + "date": "2026-01-23", + "value": 48.6 + }, + { + "date": "2026-01-29", + "value": 52.7 + }, + { + "date": "2026-02-06", + "value": 48.6 + }, + { + "date": "2026-02-12", + "value": 52.7 + }, + { + "date": "2026-02-18", + "value": 55.4 + }, + { + "date": "2026-02-24", + "value": 60.8 + }, + { + "date": "2026-02-30", + "value": 40.5 + }, + { + "date": "2026-03-04", + "value": 47.2 + }, + { + "date": "2026-03-10", + "value": 51.3 + }, + { + "date": "2026-03-16", + "value": 55.4 + }, + { + "date": "2026-03-22", + "value": 36.5 + }, + { + "date": "2026-03-28", + "value": 40.5 + }, + { + "date": "2026-04-05", + "value": 45.9 + }, + { + "date": "2026-04-11", + "value": 51.3 + }, + { + "date": "2026-04-17", + "value": 31.1 + }, + { + "date": "2026-04-23", + "value": 36.5 + }, + { + "date": "2026-04-29", + "value": 39.2 + }, + { + "date": "2026-05-06", + "value": 58.1 + }, + { + "date": "2026-05-12", + "value": 37.8 + }, + { + "date": "2026-05-18", + "value": 43.2 + }, + { + "date": "2026-05-24", + "value": 45.9 + }, + { + "date": "2026-05-30", + "value": 50.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 49.7, + "median": 49.3, + "p10": 22.7, + "p25": 32.4, + "p75": 66.6, + "p90": 76.8, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 62.8, + "median": 59.4, + "p10": 32.3, + "p25": 40.2, + "p75": 82.1, + "p90": 96.0, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 51.7, + "median": 56.7, + "p10": 20.0, + "p25": 33.8, + "p75": 72.2, + "p90": 81.5, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 50.6, + "median": 42.5, + "p10": 24.3, + "p25": 30.4, + "p75": 62.8, + "p90": 83.4, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 59.7, + "median": 64.8, + "p10": 18.6, + "p25": 40.5, + "p75": 74.2, + "p90": 98.6, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 60.1, + "median": 41.9, + "p10": 25.9, + "p25": 28.4, + "p75": 73.6, + "p90": 108.8, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 51.0, + "median": 52.7, + "p10": 42.7, + "p25": 45.9, + "p75": 55.4, + "p90": 58.6, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 45.4, + "median": 43.2, + "p10": 38.1, + "p25": 40.5, + "p75": 51.3, + "p90": 53.7, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 40.2, + "median": 39.2, + "p10": 33.2, + "p25": 36.5, + "p75": 43.2, + "p90": 48.1, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 46.2, + "median": 45.9, + "p10": 40.0, + "p25": 43.2, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 45.1, + "median": 44.6, + "p10": 39.4, + "p25": 41.9, + "p75": 48.6, + "p90": 51.0, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 51.6, + "median": 52.7, + "p10": 43.7, + "p25": 48.6, + "p75": 55.4, + "p90": 58.6, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 46.2, + "median": 47.2, + "p10": 38.1, + "p25": 40.5, + "p75": 51.3, + "p90": 53.7, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 40.8, + "median": 39.2, + "p10": 33.2, + "p25": 36.5, + "p75": 45.9, + "p90": 49.1, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 47.0, + "median": 45.9, + "p10": 40.0, + "p25": 43.2, + "p75": 50.0, + "p90": 54.8, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 59.3, + "median": 55.4, + "std": 25.8, + "min": 5.4, + "max": 155.2, + "p25": 46.3, + "p75": 67.5, + "p85": 72.9, + "p95": 110.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 7.425, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 54.0 + }, + { + "date": "2022-06-15", + "value": 29.7 + }, + { + "date": "2022-06-25", + "value": 91.8 + }, + { + "date": "2023-03-08", + "value": 5.4 + }, + { + "date": "2023-03-15", + "value": 74.2 + }, + { + "date": "2023-03-22", + "value": 155.2 + }, + { + "date": "2023-03-29", + "value": 40.5 + }, + { + "date": "2023-11-06", + "value": 83.7 + }, + { + "date": "2023-11-13", + "value": 24.3 + }, + { + "date": "2023-11-20", + "value": 114.8 + }, + { + "date": "2024-06-03", + "value": 47.2 + }, + { + "date": "2024-06-10", + "value": 97.2 + }, + { + "date": "2024-06-17", + "value": 13.5 + }, + { + "date": "2024-06-24", + "value": 64.8 + }, + { + "date": "2024-06-30", + "value": 128.2 + }, + { + "date": "2025-01-07", + "value": 37.8 + }, + { + "date": "2025-01-14", + "value": 70.2 + }, + { + "date": "2025-01-21", + "value": 20.2 + }, + { + "date": "2025-01-28", + "value": 105.3 + }, + { + "date": "2025-08-04", + "value": 56.7 + }, + { + "date": "2025-08-08", + "value": 10.8 + }, + { + "date": "2025-08-12", + "value": 87.8 + }, + { + "date": "2025-08-16", + "value": 44.6 + }, + { + "date": "2025-08-20", + "value": 135.0 + }, + { + "date": "2025-08-24", + "value": 27.0 + }, + { + "date": "2025-09-06", + "value": 55.4 + }, + { + "date": "2025-09-12", + "value": 60.8 + }, + { + "date": "2025-09-18", + "value": 64.8 + }, + { + "date": "2025-09-24", + "value": 70.2 + }, + { + "date": "2025-09-30", + "value": 45.9 + }, + { + "date": "2025-10-04", + "value": 54.0 + }, + { + "date": "2025-10-10", + "value": 59.4 + }, + { + "date": "2025-10-16", + "value": 64.8 + }, + { + "date": "2025-10-22", + "value": 40.5 + }, + { + "date": "2025-10-28", + "value": 45.9 + }, + { + "date": "2025-11-05", + "value": 67.5 + }, + { + "date": "2025-11-11", + "value": 72.9 + }, + { + "date": "2025-11-17", + "value": 48.6 + }, + { + "date": "2025-11-23", + "value": 55.4 + }, + { + "date": "2025-11-29", + "value": 59.4 + }, + { + "date": "2025-12-06", + "value": 67.5 + }, + { + "date": "2025-12-12", + "value": 43.2 + }, + { + "date": "2025-12-18", + "value": 48.6 + }, + { + "date": "2025-12-24", + "value": 52.7 + }, + { + "date": "2025-12-30", + "value": 58.1 + }, + { + "date": "2026-01-04", + "value": 37.8 + }, + { + "date": "2026-01-10", + "value": 43.2 + }, + { + "date": "2026-01-16", + "value": 47.2 + }, + { + "date": "2026-01-22", + "value": 51.3 + }, + { + "date": "2026-01-28", + "value": 56.7 + }, + { + "date": "2026-02-05", + "value": 52.7 + }, + { + "date": "2026-02-11", + "value": 55.4 + }, + { + "date": "2026-02-17", + "value": 60.8 + }, + { + "date": "2026-02-23", + "value": 64.8 + }, + { + "date": "2026-02-29", + "value": 70.2 + }, + { + "date": "2026-03-06", + "value": 50.0 + }, + { + "date": "2026-03-12", + "value": 54.0 + }, + { + "date": "2026-03-18", + "value": 59.4 + }, + { + "date": "2026-03-24", + "value": 64.8 + }, + { + "date": "2026-03-30", + "value": 40.5 + }, + { + "date": "2026-04-04", + "value": 63.5 + }, + { + "date": "2026-04-10", + "value": 67.5 + }, + { + "date": "2026-04-16", + "value": 72.9 + }, + { + "date": "2026-04-22", + "value": 48.6 + }, + { + "date": "2026-04-28", + "value": 55.4 + }, + { + "date": "2026-05-05", + "value": 62.1 + }, + { + "date": "2026-05-11", + "value": 67.5 + }, + { + "date": "2026-05-17", + "value": 43.2 + }, + { + "date": "2026-05-23", + "value": 48.6 + }, + { + "date": "2026-05-29", + "value": 52.7 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 58.5, + "median": 54.0, + "p10": 34.6, + "p25": 41.9, + "p75": 72.9, + "p90": 84.2, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 68.9, + "median": 57.4, + "p10": 15.9, + "p25": 31.7, + "p75": 94.5, + "p90": 131.0, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 74.2, + "median": 83.7, + "p10": 36.2, + "p25": 54.0, + "p75": 99.2, + "p90": 108.5, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 70.2, + "median": 64.8, + "p10": 27.0, + "p25": 47.2, + "p75": 97.2, + "p90": 115.8, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 58.5, + "median": 54.0, + "p10": 25.5, + "p25": 33.5, + "p75": 79.0, + "p90": 94.8, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 60.3, + "median": 50.6, + "p10": 18.9, + "p25": 31.5, + "p75": 80.1, + "p90": 111.4, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 59.4, + "median": 60.8, + "p10": 49.7, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 52.9, + "median": 54.0, + "p10": 42.7, + "p25": 45.9, + "p75": 59.4, + "p90": 62.6, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 60.8, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 67.5, + "p90": 70.7, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 54.0, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 58.1, + "p90": 63.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 47.2, + "median": 47.2, + "p10": 40.0, + "p25": 43.2, + "p75": 51.3, + "p90": 54.5, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 60.8, + "median": 60.8, + "p10": 53.7, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 53.7, + "median": 54.0, + "p10": 44.3, + "p25": 50.0, + "p75": 59.4, + "p90": 62.6, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 61.6, + "median": 63.5, + "p10": 51.3, + "p25": 55.4, + "p75": 67.5, + "p90": 70.7, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 54.8, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 62.1, + "p90": 65.3, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 5.9, + "median": 5.4, + "std": 2.4, + "min": 1.4, + "max": 18.9, + "p25": 4.5, + "p75": 6.8, + "p85": 6.8, + "p95": 8.9 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 4.1 + }, + { + "date": "2022-07-05", + "value": 6.8 + }, + { + "date": "2022-10-12", + "value": 2.7 + }, + { + "date": "2023-01-20", + "value": 9.5 + }, + { + "date": "2023-04-15", + "value": 5.4 + }, + { + "date": "2023-07-28", + "value": 8.1 + }, + { + "date": "2023-10-05", + "value": 4.1 + }, + { + "date": "2024-01-12", + "value": 18.9 + }, + { + "date": "2024-04-22", + "value": 5.4 + }, + { + "date": "2024-07-10", + "value": 10.8 + }, + { + "date": "2024-10-18", + "value": 4.1 + }, + { + "date": "2025-01-25", + "value": 6.8 + }, + { + "date": "2025-05-08", + "value": 1.4 + }, + { + "date": "2025-08-15", + "value": 8.1 + }, + { + "date": "2025-09-04", + "value": 4.1 + }, + { + "date": "2025-09-10", + "value": 5.4 + }, + { + "date": "2025-09-16", + "value": 5.4 + }, + { + "date": "2025-09-22", + "value": 5.4 + }, + { + "date": "2025-10-05", + "value": 4.1 + }, + { + "date": "2025-10-11", + "value": 5.4 + }, + { + "date": "2025-10-17", + "value": 5.4 + }, + { + "date": "2025-10-23", + "value": 5.4 + }, + { + "date": "2025-11-06", + "value": 5.4 + }, + { + "date": "2025-11-12", + "value": 6.8 + }, + { + "date": "2025-11-18", + "value": 6.8 + }, + { + "date": "2025-11-24", + "value": 6.8 + }, + { + "date": "2025-12-04", + "value": 5.4 + }, + { + "date": "2025-12-10", + "value": 6.8 + }, + { + "date": "2025-12-16", + "value": 6.8 + }, + { + "date": "2025-12-22", + "value": 4.1 + }, + { + "date": "2026-01-05", + "value": 5.4 + }, + { + "date": "2026-01-11", + "value": 6.8 + }, + { + "date": "2026-01-17", + "value": 4.1 + }, + { + "date": "2026-01-23", + "value": 4.1 + }, + { + "date": "2026-02-06", + "value": 6.8 + }, + { + "date": "2026-02-12", + "value": 4.1 + }, + { + "date": "2026-02-18", + "value": 5.4 + }, + { + "date": "2026-02-24", + "value": 5.4 + }, + { + "date": "2026-03-04", + "value": 4.1 + }, + { + "date": "2026-03-10", + "value": 4.1 + }, + { + "date": "2026-03-16", + "value": 5.4 + }, + { + "date": "2026-03-22", + "value": 5.4 + }, + { + "date": "2026-04-05", + "value": 5.4 + }, + { + "date": "2026-04-11", + "value": 5.4 + }, + { + "date": "2026-04-17", + "value": 6.8 + }, + { + "date": "2026-04-23", + "value": 6.8 + }, + { + "date": "2026-05-06", + "value": 5.4 + }, + { + "date": "2026-05-12", + "value": 5.4 + }, + { + "date": "2026-05-18", + "value": 6.8 + }, + { + "date": "2026-05-24", + "value": 6.8 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-01", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-04", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-07", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2023-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2024-04", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-01", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-10", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 6.5, + "median": 6.8, + "p10": 5.8, + "p25": 6.5, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2025-12", + "mean": 5.8, + "median": 6.1, + "p10": 4.5, + "p25": 5.1, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2026-01", + "mean": 5.1, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.8, + "p90": 6.3, + "n": 4 + }, + { + "month": "2026-02", + "mean": 5.4, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.8, + "p90": 6.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 6.1, + "median": 6.1, + "p10": 5.4, + "p25": 5.4, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2026-05", + "mean": 6.1, + "median": 6.1, + "p10": 5.4, + "p25": 5.4, + "p75": 6.8, + "p90": 6.8, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 23.5, + "median": 21.6, + "std": 12.2, + "min": 2.7, + "max": 74.2, + "p25": 17.6, + "p75": 25.7, + "p85": 27.5, + "p95": 50.0 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 16.875, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 16.2 + }, + { + "date": "2022-05-15", + "value": 33.8 + }, + { + "date": "2022-05-22", + "value": 10.8 + }, + { + "date": "2022-11-03", + "value": 47.2 + }, + { + "date": "2022-11-10", + "value": 20.2 + }, + { + "date": "2022-11-18", + "value": 6.8 + }, + { + "date": "2022-11-25", + "value": 29.7 + }, + { + "date": "2023-05-08", + "value": 24.3 + }, + { + "date": "2023-05-15", + "value": 54.0 + }, + { + "date": "2023-05-22", + "value": 13.5 + }, + { + "date": "2023-11-06", + "value": 74.2 + }, + { + "date": "2023-11-13", + "value": 2.7 + }, + { + "date": "2023-11-20", + "value": 37.8 + }, + { + "date": "2023-11-27", + "value": 20.2 + }, + { + "date": "2023-11-30", + "value": 10.8 + }, + { + "date": "2024-05-06", + "value": 27.0 + }, + { + "date": "2024-05-13", + "value": 60.8 + }, + { + "date": "2024-05-20", + "value": 16.2 + }, + { + "date": "2024-05-27", + "value": 4.1 + }, + { + "date": "2024-11-04", + "value": 24.3 + }, + { + "date": "2024-11-11", + "value": 40.5 + }, + { + "date": "2024-11-18", + "value": 10.8 + }, + { + "date": "2025-05-05", + "value": 29.7 + }, + { + "date": "2025-05-09", + "value": 47.2 + }, + { + "date": "2025-05-13", + "value": 6.8 + }, + { + "date": "2025-05-17", + "value": 20.2 + }, + { + "date": "2025-05-21", + "value": 56.7 + }, + { + "date": "2025-05-25", + "value": 13.5 + }, + { + "date": "2025-09-05", + "value": 18.9 + }, + { + "date": "2025-09-11", + "value": 21.6 + }, + { + "date": "2025-09-17", + "value": 23.0 + }, + { + "date": "2025-09-23", + "value": 24.3 + }, + { + "date": "2025-09-29", + "value": 25.7 + }, + { + "date": "2025-10-06", + "value": 18.9 + }, + { + "date": "2025-10-12", + "value": 20.2 + }, + { + "date": "2025-10-18", + "value": 21.6 + }, + { + "date": "2025-10-24", + "value": 24.3 + }, + { + "date": "2025-10-30", + "value": 14.9 + }, + { + "date": "2025-11-04", + "value": 24.3 + }, + { + "date": "2025-11-10", + "value": 25.7 + }, + { + "date": "2025-11-16", + "value": 27.0 + }, + { + "date": "2025-11-22", + "value": 18.9 + }, + { + "date": "2025-11-28", + "value": 20.2 + }, + { + "date": "2025-12-05", + "value": 23.0 + }, + { + "date": "2025-12-11", + "value": 25.7 + }, + { + "date": "2025-12-17", + "value": 16.2 + }, + { + "date": "2025-12-23", + "value": 18.9 + }, + { + "date": "2025-12-29", + "value": 20.2 + }, + { + "date": "2026-01-06", + "value": 23.0 + }, + { + "date": "2026-01-12", + "value": 14.9 + }, + { + "date": "2026-01-18", + "value": 16.2 + }, + { + "date": "2026-01-24", + "value": 17.6 + }, + { + "date": "2026-01-30", + "value": 18.9 + }, + { + "date": "2026-02-04", + "value": 17.6 + }, + { + "date": "2026-02-10", + "value": 18.9 + }, + { + "date": "2026-02-16", + "value": 21.6 + }, + { + "date": "2026-02-22", + "value": 23.0 + }, + { + "date": "2026-02-28", + "value": 24.3 + }, + { + "date": "2026-03-05", + "value": 17.6 + }, + { + "date": "2026-03-11", + "value": 18.9 + }, + { + "date": "2026-03-17", + "value": 20.2 + }, + { + "date": "2026-03-23", + "value": 21.6 + }, + { + "date": "2026-03-29", + "value": 24.3 + }, + { + "date": "2026-04-06", + "value": 21.6 + }, + { + "date": "2026-04-12", + "value": 24.3 + }, + { + "date": "2026-04-18", + "value": 25.7 + }, + { + "date": "2026-04-24", + "value": 27.0 + }, + { + "date": "2026-04-30", + "value": 18.9 + }, + { + "date": "2026-05-04", + "value": 21.6 + }, + { + "date": "2026-05-10", + "value": 23.0 + }, + { + "date": "2026-05-16", + "value": 25.7 + }, + { + "date": "2026-05-22", + "value": 16.2 + }, + { + "date": "2026-05-28", + "value": 18.9 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 20.2, + "median": 16.2, + "p10": 11.9, + "p25": 13.5, + "p75": 25.0, + "p90": 30.2, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 26.1, + "median": 25.0, + "p10": 10.8, + "p25": 16.9, + "p75": 34.2, + "p90": 42.0, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 30.6, + "median": 24.3, + "p10": 15.7, + "p25": 18.9, + "p75": 39.2, + "p90": 48.1, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 29.2, + "median": 20.2, + "p10": 5.9, + "p25": 10.8, + "p75": 37.8, + "p90": 59.7, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 27.0, + "median": 21.6, + "p10": 7.7, + "p25": 13.2, + "p75": 35.5, + "p90": 50.6, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 25.2, + "median": 24.3, + "p10": 13.5, + "p25": 17.6, + "p75": 32.4, + "p90": 37.3, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 29.0, + "median": 25.0, + "p10": 10.1, + "p25": 15.3, + "p75": 42.9, + "p90": 52.0, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 22.7, + "median": 23.0, + "p10": 20.0, + "p25": 21.6, + "p75": 24.3, + "p90": 25.1, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 20.0, + "median": 20.2, + "p10": 16.5, + "p25": 18.9, + "p75": 21.6, + "p90": 23.2, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 23.2, + "median": 24.3, + "p10": 19.4, + "p25": 20.2, + "p75": 25.7, + "p90": 26.5, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 20.8, + "median": 20.2, + "p10": 17.3, + "p25": 18.9, + "p75": 23.0, + "p90": 24.6, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 18.1, + "median": 17.6, + "p10": 15.4, + "p25": 16.2, + "p75": 18.9, + "p90": 21.3, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 21.1, + "median": 21.6, + "p10": 18.1, + "p25": 18.9, + "p75": 23.0, + "p90": 23.8, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 20.5, + "median": 20.2, + "p10": 18.1, + "p25": 18.9, + "p75": 21.6, + "p90": 23.2, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 23.5, + "median": 24.3, + "p10": 20.0, + "p25": 21.6, + "p75": 25.7, + "p90": 26.5, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 21.1, + "median": 21.6, + "p10": 17.3, + "p25": 18.9, + "p75": 23.0, + "p90": 24.6, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 4.3, + "median": 4.1, + "std": 1.9, + "min": 0.0, + "max": 13.5, + "p25": 4.1, + "p75": 5.4, + "p85": 5.4, + "p95": 7.0 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 2.7 + }, + { + "date": "2022-06-10", + "value": 4.1 + }, + { + "date": "2022-07-15", + "value": 1.4 + }, + { + "date": "2022-08-22", + "value": 5.4 + }, + { + "date": "2022-10-05", + "value": 2.7 + }, + { + "date": "2022-11-18", + "value": 6.8 + }, + { + "date": "2023-01-10", + "value": 4.1 + }, + { + "date": "2023-03-25", + "value": 9.5 + }, + { + "date": "2023-05-12", + "value": 2.7 + }, + { + "date": "2023-07-08", + "value": 5.4 + }, + { + "date": "2023-09-15", + "value": 1.4 + }, + { + "date": "2023-11-22", + "value": 4.1 + }, + { + "date": "2024-01-18", + "value": 13.5 + }, + { + "date": "2024-03-08", + "value": 4.1 + }, + { + "date": "2024-05-15", + "value": 2.7 + }, + { + "date": "2024-07-22", + "value": 6.8 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 5.4 + }, + { + "date": "2025-01-15", + "value": 4.1 + }, + { + "date": "2025-03-20", + "value": 2.7 + }, + { + "date": "2025-05-28", + "value": 8.1 + }, + { + "date": "2025-08-05", + "value": 4.1 + }, + { + "date": "2025-09-05", + "value": 5.4 + }, + { + "date": "2025-09-11", + "value": 5.4 + }, + { + "date": "2025-09-17", + "value": 4.1 + }, + { + "date": "2025-09-23", + "value": 4.1 + }, + { + "date": "2025-10-06", + "value": 5.4 + }, + { + "date": "2025-10-12", + "value": 2.7 + }, + { + "date": "2025-10-18", + "value": 4.1 + }, + { + "date": "2025-10-24", + "value": 4.1 + }, + { + "date": "2025-11-04", + "value": 2.7 + }, + { + "date": "2025-11-10", + "value": 2.7 + }, + { + "date": "2025-11-16", + "value": 4.1 + }, + { + "date": "2025-11-22", + "value": 4.1 + }, + { + "date": "2025-12-05", + "value": 4.1 + }, + { + "date": "2025-12-11", + "value": 4.1 + }, + { + "date": "2025-12-17", + "value": 4.1 + }, + { + "date": "2025-12-23", + "value": 5.4 + }, + { + "date": "2026-01-06", + "value": 4.1 + }, + { + "date": "2026-01-12", + "value": 4.1 + }, + { + "date": "2026-01-18", + "value": 4.1 + }, + { + "date": "2026-01-24", + "value": 5.4 + }, + { + "date": "2026-02-04", + "value": 5.4 + }, + { + "date": "2026-02-10", + "value": 5.4 + }, + { + "date": "2026-02-16", + "value": 5.4 + }, + { + "date": "2026-02-22", + "value": 4.1 + }, + { + "date": "2026-03-05", + "value": 4.1 + }, + { + "date": "2026-03-11", + "value": 5.4 + }, + { + "date": "2026-03-17", + "value": 2.7 + }, + { + "date": "2026-03-23", + "value": 4.1 + }, + { + "date": "2026-04-06", + "value": 4.1 + }, + { + "date": "2026-04-12", + "value": 2.7 + }, + { + "date": "2026-04-18", + "value": 2.7 + }, + { + "date": "2026-04-24", + "value": 4.1 + }, + { + "date": "2026-05-04", + "value": 4.1 + }, + { + "date": "2026-05-10", + "value": 4.1 + }, + { + "date": "2026-05-16", + "value": 4.1 + }, + { + "date": "2026-05-22", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-06", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2022-08", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-11", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-03", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2023-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2025-05", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.4, + "median": 3.4, + "p10": 2.7, + "p25": 2.7, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-12", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.4, + "median": 3.4, + "p10": 2.7, + "p25": 2.7, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 4.6, + "median": 4.1, + "std": 2.4, + "min": 0.0, + "max": 17.6, + "p25": 4.1, + "p75": 5.4, + "p85": 5.4, + "p95": 8.4 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 2.7 + }, + { + "date": "2022-06-13", + "value": 1.4 + }, + { + "date": "2022-07-16", + "value": 4.1 + }, + { + "date": "2022-08-26", + "value": 2.7 + }, + { + "date": "2022-10-07", + "value": 6.8 + }, + { + "date": "2022-11-23", + "value": 2.7 + }, + { + "date": "2023-01-13", + "value": 5.4 + }, + { + "date": "2023-04-01", + "value": 4.1 + }, + { + "date": "2023-05-14", + "value": 8.1 + }, + { + "date": "2023-07-12", + "value": 2.7 + }, + { + "date": "2023-09-16", + "value": 17.6 + }, + { + "date": "2023-11-25", + "value": 4.1 + }, + { + "date": "2024-01-28", + "value": 9.5 + }, + { + "date": "2024-03-11", + "value": 1.4 + }, + { + "date": "2024-05-17", + "value": 5.4 + }, + { + "date": "2024-07-27", + "value": 6.8 + }, + { + "date": "2024-09-10", + "value": 2.7 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 4.1 + }, + { + "date": "2025-03-22", + "value": 10.8 + }, + { + "date": "2025-06-03", + "value": 2.7 + }, + { + "date": "2025-08-08", + "value": 6.8 + }, + { + "date": "2025-09-04", + "value": 2.7 + }, + { + "date": "2025-09-10", + "value": 4.1 + }, + { + "date": "2025-09-16", + "value": 4.1 + }, + { + "date": "2025-09-22", + "value": 4.1 + }, + { + "date": "2025-10-05", + "value": 4.1 + }, + { + "date": "2025-10-11", + "value": 4.1 + }, + { + "date": "2025-10-17", + "value": 5.4 + }, + { + "date": "2025-10-23", + "value": 5.4 + }, + { + "date": "2025-11-06", + "value": 4.1 + }, + { + "date": "2025-11-12", + "value": 4.1 + }, + { + "date": "2025-11-18", + "value": 4.1 + }, + { + "date": "2025-11-24", + "value": 5.4 + }, + { + "date": "2025-12-04", + "value": 4.1 + }, + { + "date": "2025-12-10", + "value": 4.1 + }, + { + "date": "2025-12-16", + "value": 4.1 + }, + { + "date": "2025-12-22", + "value": 2.7 + }, + { + "date": "2026-01-05", + "value": 5.4 + }, + { + "date": "2026-01-11", + "value": 5.4 + }, + { + "date": "2026-01-17", + "value": 4.1 + }, + { + "date": "2026-01-23", + "value": 4.1 + }, + { + "date": "2026-02-06", + "value": 5.4 + }, + { + "date": "2026-02-12", + "value": 2.7 + }, + { + "date": "2026-02-18", + "value": 4.1 + }, + { + "date": "2026-02-24", + "value": 4.1 + }, + { + "date": "2026-03-04", + "value": 4.1 + }, + { + "date": "2026-03-10", + "value": 4.1 + }, + { + "date": "2026-03-16", + "value": 4.1 + }, + { + "date": "2026-03-22", + "value": 5.4 + }, + { + "date": "2026-04-05", + "value": 4.1 + }, + { + "date": "2026-04-11", + "value": 4.1 + }, + { + "date": "2026-04-17", + "value": 4.1 + }, + { + "date": "2026-04-23", + "value": 4.1 + }, + { + "date": "2026-05-06", + "value": 4.1 + }, + { + "date": "2026-05-12", + "value": 4.1 + }, + { + "date": "2026-05-18", + "value": 4.1 + }, + { + "date": "2026-05-24", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-01", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-05", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 17.6, + "median": 17.6, + "p10": 17.6, + "p25": 17.6, + "p75": 17.6, + "p90": 17.6, + "n": 1 + }, + { + "month": "2023-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2024-05", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-03", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2025-08", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.8, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.8, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 17.1, + "median": 16.2, + "std": 7.6, + "min": 2.7, + "max": 56.7, + "p25": 13.5, + "p75": 18.9, + "p85": 20.2, + "p95": 27.5 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 38.475, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 10.8 + }, + { + "date": "2023-03-25", + "value": 29.7 + }, + { + "date": "2023-09-20", + "value": 56.7 + }, + { + "date": "2024-03-15", + "value": 8.1 + }, + { + "date": "2024-03-28", + "value": 24.3 + }, + { + "date": "2024-09-05", + "value": 37.8 + }, + { + "date": "2024-09-15", + "value": 16.2 + }, + { + "date": "2024-09-25", + "value": 2.7 + }, + { + "date": "2025-03-10", + "value": 20.2 + }, + { + "date": "2025-03-22", + "value": 6.8 + }, + { + "date": "2025-07-08", + "value": 27.0 + }, + { + "date": "2025-07-22", + "value": 5.4 + }, + { + "date": "2025-09-05", + "value": 18.9 + }, + { + "date": "2025-09-11", + "value": 20.2 + }, + { + "date": "2025-09-17", + "value": 13.5 + }, + { + "date": "2025-09-23", + "value": 14.9 + }, + { + "date": "2025-09-29", + "value": 16.2 + }, + { + "date": "2025-10-06", + "value": 18.9 + }, + { + "date": "2025-10-12", + "value": 10.8 + }, + { + "date": "2025-10-18", + "value": 13.5 + }, + { + "date": "2025-10-24", + "value": 14.9 + }, + { + "date": "2025-10-30", + "value": 14.9 + }, + { + "date": "2025-11-04", + "value": 13.5 + }, + { + "date": "2025-11-10", + "value": 16.2 + }, + { + "date": "2025-11-16", + "value": 16.2 + }, + { + "date": "2025-11-22", + "value": 17.6 + }, + { + "date": "2025-11-28", + "value": 18.9 + }, + { + "date": "2025-12-05", + "value": 13.5 + }, + { + "date": "2025-12-11", + "value": 14.9 + }, + { + "date": "2025-12-17", + "value": 16.2 + }, + { + "date": "2025-12-23", + "value": 17.6 + }, + { + "date": "2025-12-29", + "value": 18.9 + }, + { + "date": "2026-01-06", + "value": 17.6 + }, + { + "date": "2026-01-12", + "value": 18.9 + }, + { + "date": "2026-01-18", + "value": 20.2 + }, + { + "date": "2026-01-24", + "value": 21.6 + }, + { + "date": "2026-01-30", + "value": 14.9 + }, + { + "date": "2026-02-04", + "value": 17.6 + }, + { + "date": "2026-02-10", + "value": 18.9 + }, + { + "date": "2026-02-16", + "value": 20.2 + }, + { + "date": "2026-02-22", + "value": 13.5 + }, + { + "date": "2026-02-28", + "value": 14.9 + }, + { + "date": "2026-03-05", + "value": 17.6 + }, + { + "date": "2026-03-11", + "value": 18.9 + }, + { + "date": "2026-03-17", + "value": 10.8 + }, + { + "date": "2026-03-23", + "value": 13.5 + }, + { + "date": "2026-03-29", + "value": 14.9 + }, + { + "date": "2026-04-06", + "value": 21.6 + }, + { + "date": "2026-04-12", + "value": 13.5 + }, + { + "date": "2026-04-18", + "value": 16.2 + }, + { + "date": "2026-04-24", + "value": 16.2 + }, + { + "date": "2026-04-30", + "value": 17.6 + }, + { + "date": "2026-05-04", + "value": 12.2 + }, + { + "date": "2026-05-10", + "value": 13.5 + }, + { + "date": "2026-05-16", + "value": 14.9 + }, + { + "date": "2026-05-22", + "value": 16.2 + }, + { + "date": "2026-05-28", + "value": 17.6 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 20.2, + "median": 20.2, + "p10": 12.7, + "p25": 15.5, + "p75": 25.0, + "p90": 27.8, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 16.2, + "median": 16.2, + "p10": 9.7, + "p25": 12.2, + "p75": 20.2, + "p90": 22.7, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 18.9, + "median": 16.2, + "p10": 5.4, + "p25": 9.5, + "p75": 27.0, + "p90": 33.5, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 13.5, + "median": 13.5, + "p10": 8.1, + "p25": 10.1, + "p75": 16.9, + "p90": 18.9, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 16.2, + "median": 16.2, + "p10": 7.6, + "p25": 10.8, + "p75": 21.6, + "p90": 24.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 16.7, + "median": 16.2, + "p10": 14.0, + "p25": 14.9, + "p75": 18.9, + "p90": 19.7, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 14.6, + "median": 14.9, + "p10": 11.9, + "p25": 13.5, + "p75": 14.9, + "p90": 17.3, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 16.5, + "median": 16.2, + "p10": 14.6, + "p25": 16.2, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 16.2, + "median": 16.2, + "p10": 14.0, + "p25": 14.9, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 18.6, + "median": 18.9, + "p10": 15.9, + "p25": 17.6, + "p75": 20.2, + "p90": 21.1, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 17.0, + "median": 17.6, + "p10": 14.0, + "p25": 14.9, + "p75": 18.9, + "p90": 19.7, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 15.1, + "median": 14.9, + "p10": 11.9, + "p25": 13.5, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 17.0, + "median": 16.2, + "p10": 14.6, + "p25": 16.2, + "p75": 17.6, + "p90": 20.0, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 14.9, + "median": 14.9, + "p10": 12.7, + "p25": 13.5, + "p75": 16.2, + "p90": 17.0, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 28.2, + "median": 28.4, + "std": 6.2, + "min": 16.2, + "max": 51.3, + "p25": 25.0, + "p75": 31.1, + "p85": 33.6, + "p95": 35.9 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 24.3 + }, + { + "date": "2023-10-12", + "value": 33.8 + }, + { + "date": "2024-04-08", + "value": 16.2 + }, + { + "date": "2024-09-20", + "value": 51.3 + }, + { + "date": "2024-10-15", + "value": 27.0 + }, + { + "date": "2025-03-25", + "value": 20.2 + }, + { + "date": "2025-04-10", + "value": 37.8 + }, + { + "date": "2025-07-30", + "value": 32.4 + }, + { + "date": "2025-09-04", + "value": 23.0 + }, + { + "date": "2025-09-10", + "value": 25.7 + }, + { + "date": "2025-09-16", + "value": 28.4 + }, + { + "date": "2025-10-05", + "value": 23.0 + }, + { + "date": "2025-10-11", + "value": 25.7 + }, + { + "date": "2025-10-17", + "value": 27.0 + }, + { + "date": "2025-11-06", + "value": 29.7 + }, + { + "date": "2025-11-12", + "value": 31.1 + }, + { + "date": "2025-11-18", + "value": 33.8 + }, + { + "date": "2025-12-04", + "value": 28.4 + }, + { + "date": "2025-12-10", + "value": 31.1 + }, + { + "date": "2025-12-16", + "value": 33.8 + }, + { + "date": "2026-01-05", + "value": 28.4 + }, + { + "date": "2026-01-11", + "value": 31.1 + }, + { + "date": "2026-01-17", + "value": 18.9 + }, + { + "date": "2026-02-06", + "value": 35.1 + }, + { + "date": "2026-02-12", + "value": 23.0 + }, + { + "date": "2026-02-18", + "value": 25.7 + }, + { + "date": "2026-03-04", + "value": 20.2 + }, + { + "date": "2026-03-10", + "value": 23.0 + }, + { + "date": "2026-03-16", + "value": 25.7 + }, + { + "date": "2026-04-05", + "value": 27.0 + }, + { + "date": "2026-04-11", + "value": 29.7 + }, + { + "date": "2026-04-17", + "value": 31.1 + }, + { + "date": "2026-05-06", + "value": 27.0 + }, + { + "date": "2026-05-12", + "value": 28.4 + }, + { + "date": "2026-05-18", + "value": 31.1 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2023-10", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-04", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2024-09", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-10", + "mean": 27.0, + "median": 27.0, + "p10": 27.0, + "p25": 27.0, + "p75": 27.0, + "p90": 27.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-07", + "mean": 32.4, + "median": 32.4, + "p10": 32.4, + "p25": 32.4, + "p75": 32.4, + "p90": 32.4, + "n": 1 + }, + { + "month": "2025-09", + "mean": 25.7, + "median": 25.7, + "p10": 23.5, + "p25": 24.3, + "p75": 27.0, + "p90": 27.8, + "n": 3 + }, + { + "month": "2025-10", + "mean": 25.2, + "median": 25.7, + "p10": 23.5, + "p25": 24.3, + "p75": 26.3, + "p90": 26.7, + "n": 3 + }, + { + "month": "2025-11", + "mean": 31.5, + "median": 31.1, + "p10": 30.0, + "p25": 30.4, + "p75": 32.4, + "p90": 33.2, + "n": 3 + }, + { + "month": "2025-12", + "mean": 31.1, + "median": 31.1, + "p10": 28.9, + "p25": 29.7, + "p75": 32.4, + "p90": 33.2, + "n": 3 + }, + { + "month": "2026-01", + "mean": 26.1, + "median": 28.4, + "p10": 20.8, + "p25": 23.6, + "p75": 29.7, + "p90": 30.5, + "n": 3 + }, + { + "month": "2026-02", + "mean": 27.9, + "median": 25.7, + "p10": 23.5, + "p25": 24.3, + "p75": 30.4, + "p90": 33.2, + "n": 3 + }, + { + "month": "2026-03", + "mean": 23.0, + "median": 23.0, + "p10": 20.8, + "p25": 21.6, + "p75": 24.3, + "p90": 25.1, + "n": 3 + }, + { + "month": "2026-04", + "mean": 29.3, + "median": 29.7, + "p10": 27.5, + "p25": 28.4, + "p75": 30.4, + "p90": 30.8, + "n": 3 + }, + { + "month": "2026-05", + "mean": 28.8, + "median": 28.4, + "p10": 27.3, + "p25": 27.7, + "p75": 29.7, + "p90": 30.5, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 42.3, + "median": 41.2, + "std": 9.6, + "min": 20.2, + "max": 74.2, + "p25": 36.5, + "p75": 48.6, + "p85": 51.3, + "p95": 56.6 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 37.8 + }, + { + "date": "2022-11-30", + "value": 47.2 + }, + { + "date": "2023-03-15", + "value": 29.7 + }, + { + "date": "2023-07-10", + "value": 56.7 + }, + { + "date": "2023-10-25", + "value": 40.5 + }, + { + "date": "2024-02-08", + "value": 74.2 + }, + { + "date": "2024-05-20", + "value": 33.8 + }, + { + "date": "2024-08-12", + "value": 51.3 + }, + { + "date": "2024-11-05", + "value": 20.2 + }, + { + "date": "2025-01-22", + "value": 43.2 + }, + { + "date": "2025-04-10", + "value": 37.8 + }, + { + "date": "2025-06-18", + "value": 60.8 + }, + { + "date": "2025-07-15", + "value": 40.5 + }, + { + "date": "2025-08-05", + "value": 29.7 + }, + { + "date": "2025-09-05", + "value": 48.6 + }, + { + "date": "2025-09-10", + "value": 51.3 + }, + { + "date": "2025-09-11", + "value": 52.7 + }, + { + "date": "2025-09-17", + "value": 35.1 + }, + { + "date": "2025-10-06", + "value": 48.6 + }, + { + "date": "2025-10-12", + "value": 31.1 + }, + { + "date": "2025-10-18", + "value": 35.1 + }, + { + "date": "2025-11-04", + "value": 36.5 + }, + { + "date": "2025-11-10", + "value": 41.9 + }, + { + "date": "2025-11-16", + "value": 44.6 + }, + { + "date": "2025-12-05", + "value": 36.5 + }, + { + "date": "2025-12-11", + "value": 39.2 + }, + { + "date": "2025-12-17", + "value": 43.2 + }, + { + "date": "2026-01-06", + "value": 35.1 + }, + { + "date": "2026-01-12", + "value": 39.2 + }, + { + "date": "2026-01-18", + "value": 41.9 + }, + { + "date": "2026-02-04", + "value": 44.6 + }, + { + "date": "2026-02-10", + "value": 48.6 + }, + { + "date": "2026-02-16", + "value": 52.7 + }, + { + "date": "2026-03-05", + "value": 44.6 + }, + { + "date": "2026-03-11", + "value": 48.6 + }, + { + "date": "2026-03-17", + "value": 31.1 + }, + { + "date": "2026-04-06", + "value": 54.0 + }, + { + "date": "2026-04-12", + "value": 36.5 + }, + { + "date": "2026-04-18", + "value": 41.9 + }, + { + "date": "2026-05-04", + "value": 32.4 + }, + { + "date": "2026-05-10", + "value": 36.5 + }, + { + "date": "2026-05-16", + "value": 39.2 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2022-11", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2023-03", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1 + }, + { + "month": "2023-10", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2024-02", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-08", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-11", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 43.2, + "median": 43.2, + "p10": 43.2, + "p25": 43.2, + "p75": 43.2, + "p90": 43.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 60.8, + "median": 60.8, + "p10": 60.8, + "p25": 60.8, + "p75": 60.8, + "p90": 60.8, + "n": 1 + }, + { + "month": "2025-07", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 47.0, + "median": 50.0, + "p10": 39.2, + "p25": 45.2, + "p75": 51.7, + "p90": 52.2, + "n": 4 + }, + { + "month": "2025-10", + "mean": 38.2, + "median": 35.1, + "p10": 31.9, + "p25": 33.1, + "p75": 41.9, + "p90": 45.9, + "n": 3 + }, + { + "month": "2025-11", + "mean": 40.9, + "median": 41.9, + "p10": 37.5, + "p25": 39.2, + "p75": 43.2, + "p90": 44.0, + "n": 3 + }, + { + "month": "2025-12", + "mean": 39.6, + "median": 39.2, + "p10": 37.0, + "p25": 37.8, + "p75": 41.2, + "p90": 42.4, + "n": 3 + }, + { + "month": "2026-01", + "mean": 38.7, + "median": 39.2, + "p10": 35.9, + "p25": 37.1, + "p75": 40.5, + "p90": 41.3, + "n": 3 + }, + { + "month": "2026-02", + "mean": 48.6, + "median": 48.6, + "p10": 45.4, + "p25": 46.6, + "p75": 50.6, + "p90": 51.8, + "n": 3 + }, + { + "month": "2026-03", + "mean": 41.4, + "median": 44.6, + "p10": 33.8, + "p25": 37.8, + "p75": 46.6, + "p90": 47.8, + "n": 3 + }, + { + "month": "2026-04", + "mean": 44.1, + "median": 41.9, + "p10": 37.5, + "p25": 39.2, + "p75": 47.9, + "p90": 51.6, + "n": 3 + }, + { + "month": "2026-05", + "mean": 36.0, + "median": 36.5, + "p10": 33.2, + "p25": 34.4, + "p75": 37.8, + "p90": 38.6, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 60.8, + "median": 59.4, + "std": 18.9, + "min": 13.5, + "max": 128.2, + "p25": 48.6, + "p75": 66.2, + "p85": 71.6, + "p95": 91.3 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 38.475, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 56.7 + }, + { + "date": "2023-05-05", + "value": 87.8 + }, + { + "date": "2023-05-20", + "value": 37.8 + }, + { + "date": "2024-01-10", + "value": 128.2 + }, + { + "date": "2024-01-25", + "value": 47.2 + }, + { + "date": "2024-08-15", + "value": 13.5 + }, + { + "date": "2025-02-05", + "value": 105.3 + }, + { + "date": "2025-02-18", + "value": 74.2 + }, + { + "date": "2025-08-10", + "value": 56.7 + }, + { + "date": "2025-08-20", + "value": 43.2 + }, + { + "date": "2025-09-06", + "value": 52.7 + }, + { + "date": "2025-09-12", + "value": 56.7 + }, + { + "date": "2025-09-18", + "value": 62.1 + }, + { + "date": "2025-10-04", + "value": 66.2 + }, + { + "date": "2025-10-10", + "value": 71.6 + }, + { + "date": "2025-10-16", + "value": 77.0 + }, + { + "date": "2025-11-05", + "value": 64.8 + }, + { + "date": "2025-11-11", + "value": 70.2 + }, + { + "date": "2025-11-17", + "value": 45.9 + }, + { + "date": "2025-12-06", + "value": 64.8 + }, + { + "date": "2025-12-12", + "value": 40.5 + }, + { + "date": "2025-12-18", + "value": 45.9 + }, + { + "date": "2026-01-04", + "value": 48.6 + }, + { + "date": "2026-01-10", + "value": 55.4 + }, + { + "date": "2026-01-16", + "value": 58.1 + }, + { + "date": "2026-02-05", + "value": 48.6 + }, + { + "date": "2026-02-11", + "value": 52.7 + }, + { + "date": "2026-02-17", + "value": 56.7 + }, + { + "date": "2026-03-06", + "value": 62.1 + }, + { + "date": "2026-03-12", + "value": 66.2 + }, + { + "date": "2026-03-18", + "value": 71.6 + }, + { + "date": "2026-04-04", + "value": 60.8 + }, + { + "date": "2026-04-10", + "value": 64.8 + }, + { + "date": "2026-04-16", + "value": 70.2 + }, + { + "date": "2026-05-05", + "value": 59.4 + }, + { + "date": "2026-05-11", + "value": 64.8 + }, + { + "date": "2026-05-17", + "value": 40.5 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 62.8, + "median": 62.8, + "p10": 42.8, + "p25": 50.4, + "p75": 75.3, + "p90": 82.8, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 87.8, + "median": 87.8, + "p10": 55.4, + "p25": 67.5, + "p75": 108.0, + "p90": 120.2, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 89.8, + "median": 89.8, + "p10": 77.4, + "p25": 82.1, + "p75": 97.6, + "p90": 102.2, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 50.0, + "median": 50.0, + "p10": 44.6, + "p25": 46.6, + "p75": 53.3, + "p90": 55.4, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 57.1, + "median": 56.7, + "p10": 53.5, + "p25": 54.7, + "p75": 59.4, + "p90": 61.0, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 71.6, + "median": 71.6, + "p10": 67.2, + "p25": 68.9, + "p75": 74.2, + "p90": 75.9, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 60.3, + "median": 64.8, + "p10": 49.7, + "p25": 55.4, + "p75": 67.5, + "p90": 69.1, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 50.4, + "median": 45.9, + "p10": 41.6, + "p25": 43.2, + "p75": 55.4, + "p90": 61.0, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 54.0, + "median": 55.4, + "p10": 50.0, + "p25": 52.0, + "p75": 56.7, + "p90": 57.5, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 52.7, + "median": 52.7, + "p10": 49.4, + "p25": 50.6, + "p75": 54.7, + "p90": 55.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 66.6, + "median": 66.2, + "p10": 62.9, + "p25": 64.1, + "p75": 68.9, + "p90": 70.5, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 65.2, + "median": 64.8, + "p10": 61.6, + "p25": 62.8, + "p75": 67.5, + "p90": 69.1, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 54.9, + "median": 59.4, + "p10": 44.3, + "p25": 50.0, + "p75": 62.1, + "p90": 63.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ], + "edges": [ + { + "source": "procurement_highland_arabica", + "target": "raw_dwell_highland_arabica", + "label": "101" + }, + { + "source": "procurement_lowland_robusta", + "target": "raw_dwell_lowland_robusta", + "label": "101" + }, + { + "source": "procurement_washed_bourbon", + "target": "raw_dwell_washed_bourbon", + "label": "101" + }, + { + "source": "raw_dwell_highland_arabica", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "raw_dwell_lowland_robusta", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "prod_duration_green_blend", + "target": "intermed_dwell_green_blend", + "label": "101" + }, + { + "source": "raw_dwell_washed_bourbon", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "intermed_dwell_green_blend", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "prod_duration_harbor_dark_roast", + "target": "prod_to_qa_pla", + "label": "101" + }, + { + "source": "post_qa_ship_pla", + "target": "direct_ship_pla", + "label": "601" + }, + { + "source": "post_qa_ship_pla", + "target": "transit_pla_hub1", + "label": "641" + }, + { + "source": "transit_pla_hub1", + "target": "dest_dwell_hub1" + }, + { + "source": "prod_to_qa_pla", + "target": "post_qa_ship_pla" + } + ], + "pipeline_summary": { + "direct": { + "label": "Direct to customer", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 29.9, + "median": 30, + "pct_of_total": 17.6, + "n": 60 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 99.8, + "median": 101, + "pct_of_total": 58.9, + "n": 60 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.6, + "median": 7, + "pct_of_total": 3.9, + "n": 60 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 33.2, + "median": 33, + "pct_of_total": 19.6, + "n": 60 + } + ], + "total_mean": 169.5, + "total_median": 171 + }, + "hub-1": { + "label": "HUB-1", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 28.4, + "median": 29, + "pct_of_total": 12.8, + "n": 40 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 102.1, + "median": 104, + "pct_of_total": 46.1, + "n": 40 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.2, + "median": 6, + "pct_of_total": 2.8, + "n": 40 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 84.8, + "median": 88, + "pct_of_total": 38.3, + "n": 40 + } + ], + "total_mean": 221.5, + "total_median": 227 + } + }, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica", + "step_ids": ["procurement_highland_arabica", "raw_dwell_highland_arabica"] + }, + { + "date": "2024-01-15", + "label": "QA process revision", + "step_ids": ["qa_hold_pla"] + } + ], + "batch_timelines": { + "batches": [ + { + "batch": "BATCH-007069", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-05-27", + "earliest_gr_date": "2024-05-29", + "earliest_production_start": "2024-07-03", + "fg_receipt_date": "2024-10-28", + "qa_release_date": "2024-11-03", + "ship_date": null, + "delivery_date": "2024-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 117, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 112, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 23 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-767678", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-13", + "earliest_gr_date": "2024-07-15", + "earliest_production_start": "2024-07-29", + "fg_receipt_date": "2024-11-05", + "qa_release_date": "2024-11-09", + "ship_date": null, + "delivery_date": "2024-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 99, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 36, + "total_days": 155, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 14, + "direct_ship_pla": 22 + } + }, + "total_from_po": 155 + }, + { + "batch": "BATCH-872783", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-25", + "earliest_gr_date": "2024-07-27", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-08", + "qa_release_date": "2024-11-15", + "ship_date": null, + "delivery_date": "2024-12-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 81, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 35, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 58, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 78, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 25 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-868247", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-20", + "earliest_gr_date": "2024-07-22", + "earliest_production_start": "2024-08-24", + "fg_receipt_date": "2024-11-10", + "qa_release_date": "2024-11-19", + "ship_date": null, + "delivery_date": "2024-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 37, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 61, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "direct_ship_pla": 20 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-775611", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-22", + "earliest_gr_date": "2024-07-24", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-22", + "qa_release_date": "2024-11-30", + "ship_date": null, + "delivery_date": "2024-12-31", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 95, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-544789", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-08", + "earliest_gr_date": "2024-07-10", + "earliest_production_start": "2024-08-05", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-12", + "ship_date": null, + "delivery_date": "2025-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 122, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 7, + "direct_ship_pla": 18 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-447665", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-14", + "earliest_gr_date": "2024-07-16", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-11", + "ship_date": null, + "delivery_date": "2025-01-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 31, + "total_days": 181, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "direct_ship_pla": 18 + } + }, + "total_from_po": 181 + }, + { + "batch": "BATCH-963613", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-26", + "fg_receipt_date": "2024-12-12", + "qa_release_date": "2024-12-19", + "ship_date": null, + "delivery_date": "2025-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 19 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-863299", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-05", + "earliest_gr_date": "2024-08-07", + "earliest_production_start": "2024-08-30", + "fg_receipt_date": "2024-12-21", + "qa_release_date": "2024-12-27", + "ship_date": null, + "delivery_date": "2025-01-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 26, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-528145", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-22", + "earliest_gr_date": "2024-08-24", + "earliest_production_start": "2024-09-11", + "fg_receipt_date": "2024-12-24", + "qa_release_date": "2024-12-30", + "ship_date": null, + "delivery_date": "2025-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 29, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 90, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 102, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 17 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-242499", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-17", + "earliest_gr_date": "2024-08-19", + "earliest_production_start": "2024-09-16", + "fg_receipt_date": "2024-12-26", + "qa_release_date": "2024-12-31", + "ship_date": null, + "delivery_date": "2025-02-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 33, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-576635", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-29", + "earliest_gr_date": "2024-10-01", + "earliest_production_start": "2024-10-26", + "fg_receipt_date": "2024-12-31", + "qa_release_date": "2025-01-07", + "ship_date": null, + "delivery_date": "2025-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 66, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 32, + "total_days": 132, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 47, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 64, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 24 + } + }, + "total_from_po": 132 + }, + { + "batch": "BATCH-221460", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-28", + "fg_receipt_date": "2025-01-01", + "qa_release_date": "2025-01-08", + "ship_date": null, + "delivery_date": "2025-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 126, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 36, + "total_days": 204, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 120, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 78, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 23 + } + }, + "total_from_po": 204 + }, + { + "batch": "BATCH-666578", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-06", + "fg_receipt_date": "2025-01-10", + "qa_release_date": "2025-01-18", + "ship_date": null, + "delivery_date": "2025-02-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-208118", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-19", + "fg_receipt_date": "2025-01-11", + "qa_release_date": "2025-01-19", + "ship_date": null, + "delivery_date": "2025-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 44, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 36, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 51, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 67, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 7, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 38, + "production_days": 7, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 15, + "direct_ship_pla": 21 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-458243", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-04", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-29", + "ship_date": null, + "delivery_date": "2025-03-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-207730", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-16", + "earliest_gr_date": "2024-09-18", + "earliest_production_start": "2024-10-14", + "fg_receipt_date": "2025-01-18", + "qa_release_date": "2025-01-22", + "ship_date": null, + "delivery_date": "2025-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 44, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 92, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 16, + "direct_ship_pla": 28 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-033995", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-27", + "earliest_gr_date": "2024-08-29", + "earliest_production_start": "2024-09-30", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-30", + "ship_date": null, + "delivery_date": "2025-03-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 114, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 18, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 17, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-559161", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-16", + "fg_receipt_date": "2025-02-14", + "qa_release_date": "2025-02-19", + "ship_date": null, + "delivery_date": "2025-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 27, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 10, + "direct_ship_pla": 17 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-043249", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-28", + "earliest_gr_date": "2024-09-30", + "earliest_production_start": "2024-10-27", + "fg_receipt_date": "2025-02-12", + "qa_release_date": "2025-02-15", + "ship_date": null, + "delivery_date": "2025-03-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 36, + "total_days": 176, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 12, + "direct_ship_pla": 24 + } + }, + "total_from_po": 176 + }, + { + "batch": "BATCH-876661", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-05", + "earliest_gr_date": "2024-10-07", + "earliest_production_start": "2024-11-06", + "fg_receipt_date": "2025-02-04", + "qa_release_date": "2025-02-11", + "ship_date": null, + "delivery_date": "2025-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 31 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-758211", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-24", + "earliest_gr_date": "2024-09-26", + "earliest_production_start": "2024-10-24", + "fg_receipt_date": "2025-02-22", + "qa_release_date": "2025-03-01", + "ship_date": null, + "delivery_date": "2025-04-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 191, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 191 + }, + { + "batch": "BATCH-198568", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-07", + "earliest_gr_date": "2024-10-09", + "earliest_production_start": "2024-10-29", + "fg_receipt_date": "2025-02-21", + "qa_release_date": "2025-03-02", + "ship_date": null, + "delivery_date": "2025-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 115, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 38, + "total_days": 184, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 13, + "direct_ship_pla": 25 + } + }, + "total_from_po": 184 + }, + { + "batch": "BATCH-499114", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-20", + "earliest_gr_date": "2024-11-22", + "earliest_production_start": "2024-12-17", + "fg_receipt_date": "2025-03-05", + "qa_release_date": "2025-03-14", + "ship_date": null, + "delivery_date": "2025-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 31, + "total_days": 145, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 33, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 145 + }, + { + "batch": "BATCH-947566", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-15", + "earliest_gr_date": "2024-10-17", + "earliest_production_start": "2024-11-17", + "fg_receipt_date": "2025-03-07", + "qa_release_date": "2025-03-10", + "ship_date": null, + "delivery_date": "2025-04-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 40, + "total_days": 186, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 14, + "direct_ship_pla": 26 + } + }, + "total_from_po": 186 + }, + { + "batch": "BATCH-154390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-25", + "earliest_gr_date": "2024-10-27", + "earliest_production_start": "2024-11-27", + "fg_receipt_date": "2025-03-10", + "qa_release_date": "2025-03-16", + "ship_date": null, + "delivery_date": "2025-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 40, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 22, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 22, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 44, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 28 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-557064", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-01", + "earliest_gr_date": "2024-12-03", + "earliest_production_start": "2025-01-02", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-05", + "ship_date": null, + "delivery_date": "2025-04-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 150, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 150 + }, + { + "batch": "BATCH-307333", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-17", + "earliest_gr_date": "2024-11-19", + "earliest_production_start": "2024-12-15", + "fg_receipt_date": "2025-03-27", + "qa_release_date": "2025-04-04", + "ship_date": null, + "delivery_date": "2025-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 32, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 73, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 16 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-891817", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-02", + "earliest_gr_date": "2024-12-04", + "earliest_production_start": "2024-12-16", + "fg_receipt_date": "2025-03-30", + "qa_release_date": "2025-04-07", + "ship_date": null, + "delivery_date": "2025-05-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 14, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 76, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 25 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-852390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-24", + "earliest_gr_date": "2024-11-26", + "earliest_production_start": "2024-12-29", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-06", + "ship_date": null, + "delivery_date": "2025-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 174, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 27 + } + }, + "total_from_po": 174 + }, + { + "batch": "BATCH-412722", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-31", + "earliest_gr_date": "2025-01-02", + "earliest_production_start": "2025-01-21", + "fg_receipt_date": "2025-04-15", + "qa_release_date": "2025-04-20", + "ship_date": null, + "delivery_date": "2025-05-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 21, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 32, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 9, + "direct_ship_pla": 23 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-357156", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-08", + "earliest_gr_date": "2024-11-10", + "earliest_production_start": "2024-12-13", + "fg_receipt_date": "2025-04-05", + "qa_release_date": "2025-04-13", + "ship_date": null, + "delivery_date": "2025-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 45, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 72, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 83, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 60, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 31 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-851698", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-04", + "earliest_gr_date": "2025-01-06", + "earliest_production_start": "2025-02-06", + "fg_receipt_date": "2025-04-22", + "qa_release_date": "2025-04-30", + "ship_date": null, + "delivery_date": "2025-06-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 75, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 33, + "total_days": 149, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 71, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 54, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 7, + "direct_ship_pla": 26 + } + }, + "total_from_po": 149 + }, + { + "batch": "BATCH-440021", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-29", + "earliest_gr_date": "2024-12-31", + "earliest_production_start": "2025-01-31", + "fg_receipt_date": "2025-05-05", + "qa_release_date": "2025-05-13", + "ship_date": null, + "delivery_date": "2025-06-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 26, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-546123", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-20", + "earliest_gr_date": "2024-12-22", + "earliest_production_start": "2025-01-18", + "fg_receipt_date": "2025-05-08", + "qa_release_date": "2025-05-15", + "ship_date": null, + "delivery_date": "2025-06-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-990560", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-29", + "earliest_gr_date": "2024-12-01", + "earliest_production_start": "2025-01-08", + "fg_receipt_date": "2025-05-16", + "qa_release_date": "2025-05-24", + "ship_date": null, + "delivery_date": "2025-06-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 40, + "seg_prodstart_to_prodfinish": 128, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 25, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 109, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 125, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-386297", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-03", + "earliest_gr_date": "2025-01-05", + "earliest_production_start": "2025-01-29", + "fg_receipt_date": "2025-05-19", + "qa_release_date": "2025-05-26", + "ship_date": null, + "delivery_date": "2025-06-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 50, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 14, + "direct_ship_pla": 15 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-947389", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-21", + "earliest_gr_date": "2025-01-23", + "earliest_production_start": "2025-02-19", + "fg_receipt_date": "2025-05-31", + "qa_release_date": "2025-06-06", + "ship_date": null, + "delivery_date": "2025-06-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 16, + "direct_ship_pla": 7 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-627234", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-26", + "earliest_gr_date": "2025-01-28", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-05-29", + "qa_release_date": "2025-06-01", + "ship_date": null, + "delivery_date": "2025-07-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 11, + "direct_ship_pla": 23 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-829707", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-14", + "earliest_gr_date": "2025-01-16", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-06-01", + "qa_release_date": "2025-06-09", + "ship_date": null, + "delivery_date": "2025-07-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 42, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-404324", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-22", + "earliest_gr_date": "2025-02-24", + "earliest_production_start": "2025-03-24", + "fg_receipt_date": "2025-06-18", + "qa_release_date": "2025-06-27", + "ship_date": null, + "delivery_date": "2025-07-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 19, + "total_days": 144, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 65, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 83, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 9, + "direct_ship_pla": 10 + } + }, + "total_from_po": 144 + }, + { + "batch": "BATCH-840018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-10", + "earliest_gr_date": "2025-02-12", + "earliest_production_start": "2025-03-15", + "fg_receipt_date": "2025-06-17", + "qa_release_date": "2025-06-21", + "ship_date": null, + "delivery_date": "2025-07-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 30, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 77, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 12, + "direct_ship_pla": 18 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-243511", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-11", + "earliest_gr_date": "2025-01-13", + "earliest_production_start": "2025-02-13", + "fg_receipt_date": "2025-06-13", + "qa_release_date": "2025-06-22", + "ship_date": null, + "delivery_date": "2025-07-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 35, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 116, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 53, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-394495", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-07", + "earliest_gr_date": "2025-02-09", + "earliest_production_start": "2025-03-14", + "fg_receipt_date": "2025-06-24", + "qa_release_date": "2025-07-02", + "ship_date": null, + "delivery_date": "2025-08-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 30, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 21 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-043032", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-15", + "earliest_gr_date": "2025-02-17", + "earliest_production_start": "2025-03-11", + "fg_receipt_date": "2025-06-29", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 33, + "total_days": 173, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 41, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 173 + }, + { + "batch": "BATCH-582158", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-26", + "earliest_gr_date": "2025-02-28", + "earliest_production_start": "2025-03-23", + "fg_receipt_date": "2025-06-28", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 38, + "total_days": 167, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 23 + } + }, + "total_from_po": 167 + }, + { + "batch": "BATCH-302264", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-30", + "earliest_gr_date": "2025-04-01", + "earliest_production_start": "2025-04-24", + "fg_receipt_date": "2025-07-16", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-08-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 24, + "total_days": 140, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 59, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 77, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 8 + } + }, + "total_from_po": 140 + }, + { + "batch": "BATCH-240076", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-14", + "qa_release_date": "2025-07-21", + "ship_date": null, + "delivery_date": "2025-08-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 151, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 151 + }, + { + "batch": "BATCH-804779", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-20", + "earliest_gr_date": "2025-02-22", + "earliest_production_start": "2025-03-22", + "fg_receipt_date": "2025-07-05", + "qa_release_date": "2025-07-12", + "ship_date": null, + "delivery_date": "2025-08-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 105, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 47, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 12, + "direct_ship_pla": 35 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-731192", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-15", + "earliest_gr_date": "2025-03-17", + "earliest_production_start": "2025-04-23", + "fg_receipt_date": "2025-07-22", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-09-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 39, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 38, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 27 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-482639", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-21", + "earliest_gr_date": "2025-02-23", + "earliest_production_start": "2025-03-30", + "fg_receipt_date": "2025-07-17", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-09-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 199, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "direct_ship_pla": 27 + } + }, + "total_from_po": 199 + }, + { + "batch": "BATCH-062870", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-01", + "earliest_gr_date": "2025-04-03", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-01", + "qa_release_date": "2025-08-07", + "ship_date": null, + "delivery_date": "2025-09-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 38, + "total_days": 166, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 87, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 26 + } + }, + "total_from_po": 166 + }, + { + "batch": "BATCH-231165", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-05", + "earliest_gr_date": "2025-05-07", + "earliest_production_start": "2025-06-09", + "fg_receipt_date": "2025-08-16", + "qa_release_date": "2025-08-22", + "ship_date": null, + "delivery_date": "2025-09-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 68, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 28, + "total_days": 137, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 43, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 14 + } + }, + "total_from_po": 137 + }, + { + "batch": "BATCH-213839", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-23", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-09-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 29, + "total_days": 164, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 47, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 164 + }, + { + "batch": "BATCH-750018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-11", + "earliest_gr_date": "2025-05-13", + "earliest_production_start": "2025-06-05", + "fg_receipt_date": "2025-08-31", + "qa_release_date": "2025-09-06", + "ship_date": null, + "delivery_date": "2025-09-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 87, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 24, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 6, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 6, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "direct_ship_pla": 17 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-880539", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-20", + "earliest_gr_date": "2025-04-22", + "earliest_production_start": "2025-05-26", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-10-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 85, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 41, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 68, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 28 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-155177", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-02", + "earliest_gr_date": "2025-05-04", + "earliest_production_start": "2025-06-18", + "fg_receipt_date": "2025-09-10", + "qa_release_date": "2025-09-16", + "ship_date": null, + "delivery_date": "2025-10-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 47, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 25, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-993261", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-29", + "earliest_gr_date": "2025-05-01", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-08-30", + "qa_release_date": "2025-09-04", + "ship_date": null, + "delivery_date": "2025-10-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 98, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 42, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 72, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 77, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 31 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-753433", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-27", + "earliest_gr_date": "2025-05-29", + "earliest_production_start": "2025-06-13", + "fg_receipt_date": "2025-09-23", + "qa_release_date": "2025-09-29", + "ship_date": null, + "delivery_date": "2025-10-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 8, + "direct_ship_pla": 15 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-476897", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-21", + "earliest_gr_date": "2025-04-23", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-09-14", + "qa_release_date": "2025-09-20", + "ship_date": null, + "delivery_date": "2025-10-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 25 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-521582", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-18", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-11-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 98, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 70, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 43, + "dest_dwell_hub1": 41 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-281803", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-07", + "fg_receipt_date": "2025-07-28", + "qa_release_date": "2025-08-01", + "ship_date": null, + "delivery_date": "2025-11-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 82, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 98, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-276962", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-05", + "earliest_gr_date": "2025-04-07", + "earliest_production_start": "2025-05-05", + "fg_receipt_date": "2025-08-17", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-11-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 79, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 101, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-217426", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-15", + "earliest_gr_date": "2025-04-17", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-08-24", + "qa_release_date": "2025-09-03", + "ship_date": null, + "delivery_date": "2025-11-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 10, + "seg_qa_to_customer": 76, + "total_days": 217, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 72, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 10, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 18, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 217 + }, + { + "batch": "BATCH-679445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-01", + "earliest_gr_date": "2025-05-03", + "earliest_production_start": "2025-06-03", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-11-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 77, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 62, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 36 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-584703", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-19", + "earliest_gr_date": "2025-04-21", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-09-06", + "qa_release_date": "2025-09-13", + "ship_date": null, + "delivery_date": "2025-11-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 77, + "total_days": 224, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 224 + }, + { + "batch": "BATCH-320907", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-03", + "earliest_gr_date": "2025-05-05", + "earliest_production_start": "2025-06-01", + "fg_receipt_date": "2025-08-12", + "qa_release_date": "2025-08-21", + "ship_date": null, + "delivery_date": "2025-12-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 72, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 106, + "total_days": 216, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 54, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 69, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 216 + }, + { + "batch": "BATCH-469894", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-09", + "earliest_gr_date": "2025-04-11", + "earliest_production_start": "2025-05-12", + "fg_receipt_date": "2025-08-29", + "qa_release_date": "2025-09-05", + "ship_date": null, + "delivery_date": "2025-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 96, + "total_days": 245, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 45, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 245 + }, + { + "batch": "BATCH-119167", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-10", + "earliest_gr_date": "2025-05-12", + "earliest_production_start": "2025-05-30", + "fg_receipt_date": "2025-09-19", + "qa_release_date": "2025-09-26", + "ship_date": null, + "delivery_date": "2025-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 80, + "total_days": 219, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 95, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 74, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 219 + }, + { + "batch": "BATCH-850977", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-17", + "earliest_gr_date": "2025-05-19", + "earliest_production_start": "2025-06-14", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-10-01", + "ship_date": null, + "delivery_date": "2025-12-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 81, + "total_days": 218, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 42, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 39 + } + }, + "total_from_po": 218 + }, + { + "batch": "BATCH-315004", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-21", + "earliest_gr_date": "2025-06-23", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-10-06", + "qa_release_date": "2025-10-14", + "ship_date": null, + "delivery_date": "2025-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 71, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 73, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 22, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-753733", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-04", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-09-28", + "ship_date": null, + "delivery_date": "2026-01-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 95, + "total_days": 211, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 80, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 52 + } + }, + "total_from_po": 211 + }, + { + "batch": "BATCH-006984", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-29", + "earliest_gr_date": "2025-05-31", + "earliest_production_start": "2025-06-15", + "fg_receipt_date": "2025-09-20", + "qa_release_date": "2025-09-27", + "ship_date": null, + "delivery_date": "2026-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 101, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 45, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 49 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-962763", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-06", + "fg_receipt_date": "2025-10-26", + "qa_release_date": "2025-11-02", + "ship_date": null, + "delivery_date": "2026-01-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 71, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 35 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-885445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-06-29", + "fg_receipt_date": "2025-10-03", + "qa_release_date": "2025-10-04", + "ship_date": null, + "delivery_date": "2026-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 1, + "seg_qa_to_customer": 105, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 1, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 63 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-622159", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-31", + "earliest_gr_date": "2025-06-02", + "earliest_production_start": "2025-06-26", + "fg_receipt_date": "2025-10-17", + "qa_release_date": "2025-10-23", + "ship_date": null, + "delivery_date": "2026-01-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 92, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-990714", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-03", + "earliest_gr_date": "2025-06-05", + "earliest_production_start": "2025-07-02", + "fg_receipt_date": "2025-10-14", + "qa_release_date": "2025-10-18", + "ship_date": null, + "delivery_date": "2026-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 102, + "total_days": 239, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 239 + }, + { + "batch": "BATCH-479016", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-14", + "earliest_gr_date": "2025-06-16", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-13", + "qa_release_date": "2025-11-19", + "ship_date": null, + "delivery_date": "2026-02-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 118, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 76, + "total_days": 234, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 96, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 114, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 34 + } + }, + "total_from_po": 234 + }, + { + "batch": "BATCH-080863", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-26", + "earliest_gr_date": "2025-06-28", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-12", + "ship_date": null, + "delivery_date": "2026-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 88, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-910231", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-05", + "earliest_gr_date": "2025-07-07", + "earliest_production_start": "2025-08-11", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-16", + "ship_date": null, + "delivery_date": "2026-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 84, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 75, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 86, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-997425", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-07", + "earliest_gr_date": "2025-08-09", + "earliest_production_start": "2025-09-06", + "fg_receipt_date": "2025-12-04", + "qa_release_date": "2025-12-12", + "ship_date": null, + "delivery_date": "2026-02-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 69, + "total_days": 196, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 24, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 37, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 30 + } + }, + "total_from_po": 196 + }, + { + "batch": "BATCH-618940", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-19", + "earliest_gr_date": "2025-06-21", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-11-29", + "qa_release_date": "2025-12-02", + "ship_date": null, + "delivery_date": "2026-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 125, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 84, + "total_days": 250, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 104, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 121, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 43, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 250 + }, + { + "batch": "BATCH-029240", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-14", + "earliest_gr_date": "2025-07-16", + "earliest_production_start": "2025-08-02", + "fg_receipt_date": "2025-11-19", + "qa_release_date": "2025-11-25", + "ship_date": null, + "delivery_date": "2026-03-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 231, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 77, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 44, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 231 + }, + { + "batch": "BATCH-013796", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-04", + "qa_release_date": "2026-01-13", + "ship_date": null, + "delivery_date": "2026-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 53, + "total_days": 202, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 27, + "dest_dwell_hub1": 15 + } + }, + "total_from_po": 202 + }, + { + "batch": "BATCH-563928", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-16", + "fg_receipt_date": "2025-12-08", + "qa_release_date": "2025-12-11", + "ship_date": null, + "delivery_date": "2026-03-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 92, + "total_days": 208, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 208 + }, + { + "batch": "BATCH-263609", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-12", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-10", + "ship_date": null, + "delivery_date": "2026-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 67, + "total_days": 215, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 20, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 15, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 215 + }, + { + "batch": "BATCH-786903", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-30", + "earliest_gr_date": "2025-09-01", + "earliest_production_start": "2025-09-23", + "fg_receipt_date": "2026-01-22", + "qa_release_date": "2026-01-28", + "ship_date": null, + "delivery_date": "2026-03-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 55, + "total_days": 206, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 103, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 17, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 17, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 206 + }, + { + "batch": "BATCH-676932", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-13", + "fg_receipt_date": "2025-12-19", + "qa_release_date": "2025-12-25", + "ship_date": null, + "delivery_date": "2026-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 94, + "total_days": 226, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 35, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 51, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 226 + }, + { + "batch": "BATCH-341567", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-10", + "earliest_gr_date": "2025-08-12", + "earliest_production_start": "2025-09-05", + "fg_receipt_date": "2025-12-27", + "qa_release_date": "2026-01-01", + "ship_date": null, + "delivery_date": "2026-04-04", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 93, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 23, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-162748", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-25", + "earliest_gr_date": "2025-08-27", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-09", + "ship_date": null, + "delivery_date": "2026-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 90, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 33, + "dest_dwell_hub1": 46 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-322485", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-08", + "earliest_gr_date": "2025-10-10", + "earliest_production_start": "2025-10-27", + "fg_receipt_date": "2026-02-01", + "qa_release_date": "2026-02-10", + "ship_date": null, + "delivery_date": "2026-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 63, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 36, + "dest_dwell_hub1": 16 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-780123", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-02", + "earliest_gr_date": "2025-09-04", + "earliest_production_start": "2025-10-02", + "fg_receipt_date": "2026-01-31", + "qa_release_date": "2026-02-08", + "ship_date": null, + "delivery_date": "2026-04-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 71, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 101, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-219665", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-06", + "earliest_gr_date": "2025-10-08", + "earliest_production_start": "2025-10-22", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 69, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 4, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-254225", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-08", + "earliest_gr_date": "2025-09-10", + "earliest_production_start": "2025-09-30", + "fg_receipt_date": "2026-01-28", + "qa_release_date": "2026-02-03", + "ship_date": null, + "delivery_date": "2026-05-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 87, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 115, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-311884", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-12", + "earliest_gr_date": "2025-09-14", + "earliest_production_start": "2025-10-10", + "fg_receipt_date": "2026-01-29", + "qa_release_date": "2026-02-04", + "ship_date": null, + "delivery_date": "2026-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 91, + "total_days": 236, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 236 + }, + { + "batch": "BATCH-534136", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-26", + "earliest_gr_date": "2025-09-28", + "earliest_production_start": "2025-11-08", + "fg_receipt_date": "2026-02-10", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 43, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 86, + "total_days": 228, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 40, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 228 + }, + { + "batch": "BATCH-718060", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-29", + "earliest_gr_date": "2025-10-01", + "earliest_production_start": "2025-11-09", + "fg_receipt_date": "2026-02-24", + "qa_release_date": "2026-02-28", + "ship_date": null, + "delivery_date": "2026-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 41, + "seg_prodstart_to_prodfinish": 107, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 78, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 103, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 14, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-802602", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-12", + "earliest_gr_date": "2025-10-14", + "earliest_production_start": "2025-11-04", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 51 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-136204", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-05", + "earliest_gr_date": "2025-10-07", + "earliest_production_start": "2025-11-05", + "fg_receipt_date": "2026-02-25", + "qa_release_date": "2026-03-03", + "ship_date": null, + "delivery_date": "2026-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 86, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 53, + "dest_dwell_hub1": 19 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-949254", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-14", + "earliest_gr_date": "2025-10-16", + "earliest_production_start": "2025-11-18", + "fg_receipt_date": "2026-02-19", + "qa_release_date": "2026-02-24", + "ship_date": null, + "delivery_date": "2026-06-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 93, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 99, + "total_days": 232, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 74, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 89, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 55 + } + }, + "total_from_po": 232 + } + ], + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.3, + "median": 30, + "p25": 25, + "p75": 34, + "n": 100 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 100.7, + "median": 102, + "p25": 90, + "p75": 112, + "n": 100 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.5, + "median": 7, + "p25": 6, + "p75": 8, + "n": 100 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 53.8, + "median": 40, + "p25": 31, + "p75": 81, + "n": 100 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 190.3, + "median": 188, + "p25": 167, + "p75": 222, + "n": 100 + } + }, + "per_route": { + "direct": { + "label": "Direct to customer", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.9, + "median": 30, + "p25": 26, + "p75": 35, + "n": 60 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 99.8, + "median": 101, + "p25": 90, + "p75": 110, + "n": 60 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.6, + "median": 7, + "p25": 6, + "p75": 8, + "n": 60 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 33.2, + "median": 33, + "p25": 29, + "p75": 38, + "n": 60 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 169.5, + "median": 170, + "p25": 159, + "p75": 182, + "n": 60 + } + } + }, + "hub-1": { + "label": "HUB-1", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 28.4, + "median": 29, + "p25": 24, + "p75": 33, + "n": 40 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 102.1, + "median": 104, + "p25": 96, + "p75": 113, + "n": 40 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.2, + "median": 6, + "p25": 5, + "p75": 8, + "n": 40 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 84.8, + "median": 88, + "p25": 76, + "p75": 96, + "n": 40 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 221.6, + "median": 223, + "p25": 215, + "p75": 232, + "n": 40 + } + } + } + }, + "coverage": { + "traced": 100, + "total": 100 + } + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/dest_dwell_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/dest_dwell_hub1.json new file mode 100644 index 00000000000..e01560fdc97 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/dest_dwell_hub1.json @@ -0,0 +1,432 @@ +{ + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "durations": [ + 56.7, 87.8, 37.8, 128.2, 47.2, 13.5, 105.3, 74.2, 56.7, 43.2, 52.7, 56.7, + 62.1, 66.2, 71.6, 77.0, 64.8, 70.2, 45.9, 64.8, 40.5, 45.9, 48.6, 55.4, + 58.1, 48.6, 52.7, 56.7, 62.1, 66.2, 71.6, 60.8, 64.8, 70.2, 59.4, 64.8, 40.5 + ], + "observations": [ + { + "date": "2022-09-15", + "value": 56.7 + }, + { + "date": "2023-05-05", + "value": 87.8 + }, + { + "date": "2023-05-20", + "value": 37.8 + }, + { + "date": "2024-01-10", + "value": 128.2 + }, + { + "date": "2024-01-25", + "value": 47.2 + }, + { + "date": "2024-08-15", + "value": 13.5 + }, + { + "date": "2025-02-05", + "value": 105.3 + }, + { + "date": "2025-02-18", + "value": 74.2 + }, + { + "date": "2025-08-10", + "value": 56.7 + }, + { + "date": "2025-08-20", + "value": 43.2 + }, + { + "date": "2025-09-06", + "value": 52.7 + }, + { + "date": "2025-09-12", + "value": 56.7 + }, + { + "date": "2025-09-18", + "value": 62.1 + }, + { + "date": "2025-10-04", + "value": 66.2 + }, + { + "date": "2025-10-10", + "value": 71.6 + }, + { + "date": "2025-10-16", + "value": 77.0 + }, + { + "date": "2025-11-05", + "value": 64.8 + }, + { + "date": "2025-11-11", + "value": 70.2 + }, + { + "date": "2025-11-17", + "value": 45.9 + }, + { + "date": "2025-12-06", + "value": 64.8 + }, + { + "date": "2025-12-12", + "value": 40.5 + }, + { + "date": "2025-12-18", + "value": 45.9 + }, + { + "date": "2026-01-04", + "value": 48.6 + }, + { + "date": "2026-01-10", + "value": 55.4 + }, + { + "date": "2026-01-16", + "value": 58.1 + }, + { + "date": "2026-02-05", + "value": 48.6 + }, + { + "date": "2026-02-11", + "value": 52.7 + }, + { + "date": "2026-02-17", + "value": 56.7 + }, + { + "date": "2026-03-06", + "value": 62.1 + }, + { + "date": "2026-03-12", + "value": 66.2 + }, + { + "date": "2026-03-18", + "value": 71.6 + }, + { + "date": "2026-04-04", + "value": 60.8 + }, + { + "date": "2026-04-10", + "value": 64.8 + }, + { + "date": "2026-04-16", + "value": 70.2 + }, + { + "date": "2026-05-05", + "value": 59.4 + }, + { + "date": "2026-05-11", + "value": 64.8 + }, + { + "date": "2026-05-17", + "value": 40.5 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 62.8, + "median": 62.8, + "p10": 42.8, + "p25": 50.4, + "p75": 75.3, + "p90": 82.8, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 87.8, + "median": 87.8, + "p10": 55.4, + "p25": 67.5, + "p75": 108.0, + "p90": 120.2, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 89.8, + "median": 89.8, + "p10": 77.4, + "p25": 82.1, + "p75": 97.6, + "p90": 102.2, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 50.0, + "median": 50.0, + "p10": 44.6, + "p25": 46.6, + "p75": 53.3, + "p90": 55.4, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 57.1, + "median": 56.7, + "p10": 53.5, + "p25": 54.7, + "p75": 59.4, + "p90": 61.0, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 71.6, + "median": 71.6, + "p10": 67.2, + "p25": 68.9, + "p75": 74.2, + "p90": 75.9, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 60.3, + "median": 64.8, + "p10": 49.7, + "p25": 55.4, + "p75": 67.5, + "p90": 69.1, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 50.4, + "median": 45.9, + "p10": 41.6, + "p25": 43.2, + "p75": 55.4, + "p90": 61.0, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 54.0, + "median": 55.4, + "p10": 50.0, + "p25": 52.0, + "p75": 56.7, + "p90": 57.5, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 52.7, + "median": 52.7, + "p10": 49.4, + "p25": 50.6, + "p75": 54.7, + "p90": 55.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 66.6, + "median": 66.2, + "p10": 62.9, + "p25": 64.1, + "p75": 68.9, + "p90": 70.5, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 65.2, + "median": 64.8, + "p10": 61.6, + "p25": 62.8, + "p75": 67.5, + "p90": 69.1, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 54.9, + "median": 59.4, + "p10": 44.3, + "p25": 50.0, + "p75": 62.1, + "p90": 63.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "stats": { + "n": 37, + "mean": 60.8, + "median": 59.4, + "std": 14.0, + "min": 13.5, + "max": 128.2, + "p25": 48.6, + "p75": 66.2, + "p85": 71.6, + "p95": 87.8 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 38.475, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/intermed_dwell_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/intermed_dwell_green_blend.json new file mode 100644 index 00000000000..7aabddecaca --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/intermed_dwell_green_blend.json @@ -0,0 +1,595 @@ +{ + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "durations": [ + 16.2, 33.8, 10.8, 47.2, 20.2, 6.8, 29.7, 24.3, 54.0, 13.5, 74.2, 2.7, 37.8, + 20.2, 10.8, 27.0, 60.8, 16.2, 4.1, 24.3, 40.5, 10.8, 29.7, 47.2, 6.8, 20.2, + 56.7, 13.5, 18.9, 21.6, 23.0, 24.3, 25.7, 18.9, 20.2, 21.6, 24.3, 14.9, + 24.3, 25.7, 27.0, 18.9, 20.2, 23.0, 25.7, 16.2, 18.9, 20.2, 23.0, 14.9, + 16.2, 17.6, 18.9, 17.6, 18.9, 21.6, 23.0, 24.3, 17.6, 18.9, 20.2, 21.6, + 24.3, 21.6, 24.3, 25.7, 27.0, 18.9, 21.6, 23.0, 25.7, 16.2, 18.9 + ], + "observations": [ + { + "date": "2022-05-05", + "value": 16.2 + }, + { + "date": "2022-05-15", + "value": 33.8 + }, + { + "date": "2022-05-22", + "value": 10.8 + }, + { + "date": "2022-11-03", + "value": 47.2 + }, + { + "date": "2022-11-10", + "value": 20.2 + }, + { + "date": "2022-11-18", + "value": 6.8 + }, + { + "date": "2022-11-25", + "value": 29.7 + }, + { + "date": "2023-05-08", + "value": 24.3 + }, + { + "date": "2023-05-15", + "value": 54.0 + }, + { + "date": "2023-05-22", + "value": 13.5 + }, + { + "date": "2023-11-06", + "value": 74.2 + }, + { + "date": "2023-11-13", + "value": 2.7 + }, + { + "date": "2023-11-20", + "value": 37.8 + }, + { + "date": "2023-11-27", + "value": 20.2 + }, + { + "date": "2023-11-30", + "value": 10.8 + }, + { + "date": "2024-05-06", + "value": 27.0 + }, + { + "date": "2024-05-13", + "value": 60.8 + }, + { + "date": "2024-05-20", + "value": 16.2 + }, + { + "date": "2024-05-27", + "value": 4.1 + }, + { + "date": "2024-11-04", + "value": 24.3 + }, + { + "date": "2024-11-11", + "value": 40.5 + }, + { + "date": "2024-11-18", + "value": 10.8 + }, + { + "date": "2025-05-05", + "value": 29.7 + }, + { + "date": "2025-05-09", + "value": 47.2 + }, + { + "date": "2025-05-13", + "value": 6.8 + }, + { + "date": "2025-05-17", + "value": 20.2 + }, + { + "date": "2025-05-21", + "value": 56.7 + }, + { + "date": "2025-05-25", + "value": 13.5 + }, + { + "date": "2025-09-05", + "value": 18.9 + }, + { + "date": "2025-09-11", + "value": 21.6 + }, + { + "date": "2025-09-17", + "value": 23.0 + }, + { + "date": "2025-09-23", + "value": 24.3 + }, + { + "date": "2025-09-29", + "value": 25.7 + }, + { + "date": "2025-10-06", + "value": 18.9 + }, + { + "date": "2025-10-12", + "value": 20.2 + }, + { + "date": "2025-10-18", + "value": 21.6 + }, + { + "date": "2025-10-24", + "value": 24.3 + }, + { + "date": "2025-10-30", + "value": 14.9 + }, + { + "date": "2025-11-04", + "value": 24.3 + }, + { + "date": "2025-11-10", + "value": 25.7 + }, + { + "date": "2025-11-16", + "value": 27.0 + }, + { + "date": "2025-11-22", + "value": 18.9 + }, + { + "date": "2025-11-28", + "value": 20.2 + }, + { + "date": "2025-12-05", + "value": 23.0 + }, + { + "date": "2025-12-11", + "value": 25.7 + }, + { + "date": "2025-12-17", + "value": 16.2 + }, + { + "date": "2025-12-23", + "value": 18.9 + }, + { + "date": "2025-12-29", + "value": 20.2 + }, + { + "date": "2026-01-06", + "value": 23.0 + }, + { + "date": "2026-01-12", + "value": 14.9 + }, + { + "date": "2026-01-18", + "value": 16.2 + }, + { + "date": "2026-01-24", + "value": 17.6 + }, + { + "date": "2026-01-30", + "value": 18.9 + }, + { + "date": "2026-02-04", + "value": 17.6 + }, + { + "date": "2026-02-10", + "value": 18.9 + }, + { + "date": "2026-02-16", + "value": 21.6 + }, + { + "date": "2026-02-22", + "value": 23.0 + }, + { + "date": "2026-02-28", + "value": 24.3 + }, + { + "date": "2026-03-05", + "value": 17.6 + }, + { + "date": "2026-03-11", + "value": 18.9 + }, + { + "date": "2026-03-17", + "value": 20.2 + }, + { + "date": "2026-03-23", + "value": 21.6 + }, + { + "date": "2026-03-29", + "value": 24.3 + }, + { + "date": "2026-04-06", + "value": 21.6 + }, + { + "date": "2026-04-12", + "value": 24.3 + }, + { + "date": "2026-04-18", + "value": 25.7 + }, + { + "date": "2026-04-24", + "value": 27.0 + }, + { + "date": "2026-04-30", + "value": 18.9 + }, + { + "date": "2026-05-04", + "value": 21.6 + }, + { + "date": "2026-05-10", + "value": 23.0 + }, + { + "date": "2026-05-16", + "value": 25.7 + }, + { + "date": "2026-05-22", + "value": 16.2 + }, + { + "date": "2026-05-28", + "value": 18.9 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 20.2, + "median": 16.2, + "p10": 11.9, + "p25": 13.5, + "p75": 25.0, + "p90": 30.2, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 26.1, + "median": 25.0, + "p10": 10.8, + "p25": 16.9, + "p75": 34.2, + "p90": 42.0, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 30.6, + "median": 24.3, + "p10": 15.7, + "p25": 18.9, + "p75": 39.2, + "p90": 48.1, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 29.2, + "median": 20.2, + "p10": 5.9, + "p25": 10.8, + "p75": 37.8, + "p90": 59.7, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 27.0, + "median": 21.6, + "p10": 7.7, + "p25": 13.2, + "p75": 35.5, + "p90": 50.6, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 25.2, + "median": 24.3, + "p10": 13.5, + "p25": 17.6, + "p75": 32.4, + "p90": 37.3, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 29.0, + "median": 25.0, + "p10": 10.1, + "p25": 15.3, + "p75": 42.9, + "p90": 52.0, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 22.7, + "median": 23.0, + "p10": 20.0, + "p25": 21.6, + "p75": 24.3, + "p90": 25.1, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 20.0, + "median": 20.2, + "p10": 16.5, + "p25": 18.9, + "p75": 21.6, + "p90": 23.2, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 23.2, + "median": 24.3, + "p10": 19.4, + "p25": 20.2, + "p75": 25.7, + "p90": 26.5, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 20.8, + "median": 20.2, + "p10": 17.3, + "p25": 18.9, + "p75": 23.0, + "p90": 24.6, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 18.1, + "median": 17.6, + "p10": 15.4, + "p25": 16.2, + "p75": 18.9, + "p90": 21.3, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 21.1, + "median": 21.6, + "p10": 18.1, + "p25": 18.9, + "p75": 23.0, + "p90": 23.8, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 20.5, + "median": 20.2, + "p10": 18.1, + "p25": 18.9, + "p75": 21.6, + "p90": 23.2, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 23.5, + "median": 24.3, + "p10": 20.0, + "p25": 21.6, + "p75": 25.7, + "p90": 26.5, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 21.1, + "median": 21.6, + "p10": 17.3, + "p25": 18.9, + "p75": 23.0, + "p90": 24.6, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "stats": { + "n": 73, + "mean": 23.5, + "median": 21.6, + "std": 9.0, + "min": 2.7, + "max": 74.2, + "p25": 17.6, + "p75": 25.7, + "p85": 27.0, + "p95": 47.2 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "annotations": [], + "cost": { + "unit_price": 16.875, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 28, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/post_qa_ship_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/post_qa_ship_pla.json new file mode 100644 index 00000000000..e200ac8b450 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/post_qa_ship_pla.json @@ -0,0 +1,514 @@ +{ + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "durations": [ + 10.8, 29.7, 56.7, 8.1, 24.3, 37.8, 16.2, 2.7, 20.2, 6.8, 27.0, 5.4, 18.9, + 20.2, 13.5, 14.9, 16.2, 18.9, 10.8, 13.5, 14.9, 14.9, 13.5, 16.2, 16.2, + 17.6, 18.9, 13.5, 14.9, 16.2, 17.6, 18.9, 17.6, 18.9, 20.2, 21.6, 14.9, + 17.6, 18.9, 20.2, 13.5, 14.9, 17.6, 18.9, 10.8, 13.5, 14.9, 21.6, 13.5, + 16.2, 16.2, 17.6, 12.2, 13.5, 14.9, 16.2, 17.6 + ], + "observations": [ + { + "date": "2023-03-10", + "value": 10.8 + }, + { + "date": "2023-03-25", + "value": 29.7 + }, + { + "date": "2023-09-20", + "value": 56.7 + }, + { + "date": "2024-03-15", + "value": 8.1 + }, + { + "date": "2024-03-28", + "value": 24.3 + }, + { + "date": "2024-09-05", + "value": 37.8 + }, + { + "date": "2024-09-15", + "value": 16.2 + }, + { + "date": "2024-09-25", + "value": 2.7 + }, + { + "date": "2025-03-10", + "value": 20.2 + }, + { + "date": "2025-03-22", + "value": 6.8 + }, + { + "date": "2025-07-08", + "value": 27.0 + }, + { + "date": "2025-07-22", + "value": 5.4 + }, + { + "date": "2025-09-05", + "value": 18.9 + }, + { + "date": "2025-09-11", + "value": 20.2 + }, + { + "date": "2025-09-17", + "value": 13.5 + }, + { + "date": "2025-09-23", + "value": 14.9 + }, + { + "date": "2025-09-29", + "value": 16.2 + }, + { + "date": "2025-10-06", + "value": 18.9 + }, + { + "date": "2025-10-12", + "value": 10.8 + }, + { + "date": "2025-10-18", + "value": 13.5 + }, + { + "date": "2025-10-24", + "value": 14.9 + }, + { + "date": "2025-10-30", + "value": 14.9 + }, + { + "date": "2025-11-04", + "value": 13.5 + }, + { + "date": "2025-11-10", + "value": 16.2 + }, + { + "date": "2025-11-16", + "value": 16.2 + }, + { + "date": "2025-11-22", + "value": 17.6 + }, + { + "date": "2025-11-28", + "value": 18.9 + }, + { + "date": "2025-12-05", + "value": 13.5 + }, + { + "date": "2025-12-11", + "value": 14.9 + }, + { + "date": "2025-12-17", + "value": 16.2 + }, + { + "date": "2025-12-23", + "value": 17.6 + }, + { + "date": "2025-12-29", + "value": 18.9 + }, + { + "date": "2026-01-06", + "value": 17.6 + }, + { + "date": "2026-01-12", + "value": 18.9 + }, + { + "date": "2026-01-18", + "value": 20.2 + }, + { + "date": "2026-01-24", + "value": 21.6 + }, + { + "date": "2026-01-30", + "value": 14.9 + }, + { + "date": "2026-02-04", + "value": 17.6 + }, + { + "date": "2026-02-10", + "value": 18.9 + }, + { + "date": "2026-02-16", + "value": 20.2 + }, + { + "date": "2026-02-22", + "value": 13.5 + }, + { + "date": "2026-02-28", + "value": 14.9 + }, + { + "date": "2026-03-05", + "value": 17.6 + }, + { + "date": "2026-03-11", + "value": 18.9 + }, + { + "date": "2026-03-17", + "value": 10.8 + }, + { + "date": "2026-03-23", + "value": 13.5 + }, + { + "date": "2026-03-29", + "value": 14.9 + }, + { + "date": "2026-04-06", + "value": 21.6 + }, + { + "date": "2026-04-12", + "value": 13.5 + }, + { + "date": "2026-04-18", + "value": 16.2 + }, + { + "date": "2026-04-24", + "value": 16.2 + }, + { + "date": "2026-04-30", + "value": 17.6 + }, + { + "date": "2026-05-04", + "value": 12.2 + }, + { + "date": "2026-05-10", + "value": 13.5 + }, + { + "date": "2026-05-16", + "value": 14.9 + }, + { + "date": "2026-05-22", + "value": 16.2 + }, + { + "date": "2026-05-28", + "value": 17.6 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 20.2, + "median": 20.2, + "p10": 12.7, + "p25": 15.5, + "p75": 25.0, + "p90": 27.8, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 16.2, + "median": 16.2, + "p10": 9.7, + "p25": 12.2, + "p75": 20.2, + "p90": 22.7, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 18.9, + "median": 16.2, + "p10": 5.4, + "p25": 9.5, + "p75": 27.0, + "p90": 33.5, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 13.5, + "median": 13.5, + "p10": 8.1, + "p25": 10.1, + "p75": 16.9, + "p90": 18.9, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 16.2, + "median": 16.2, + "p10": 7.6, + "p25": 10.8, + "p75": 21.6, + "p90": 24.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 16.7, + "median": 16.2, + "p10": 14.0, + "p25": 14.9, + "p75": 18.9, + "p90": 19.7, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 14.6, + "median": 14.9, + "p10": 11.9, + "p25": 13.5, + "p75": 14.9, + "p90": 17.3, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 16.5, + "median": 16.2, + "p10": 14.6, + "p25": 16.2, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 16.2, + "median": 16.2, + "p10": 14.0, + "p25": 14.9, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 18.6, + "median": 18.9, + "p10": 15.9, + "p25": 17.6, + "p75": 20.2, + "p90": 21.1, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 17.0, + "median": 17.6, + "p10": 14.0, + "p25": 14.9, + "p75": 18.9, + "p90": 19.7, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 15.1, + "median": 14.9, + "p10": 11.9, + "p25": 13.5, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 17.0, + "median": 16.2, + "p10": 14.6, + "p25": 16.2, + "p75": 17.6, + "p90": 20.0, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 14.9, + "median": 14.9, + "p10": 12.7, + "p25": 13.5, + "p75": 16.2, + "p90": 17.0, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "stats": { + "n": 57, + "mean": 17.2, + "median": 16.2, + "std": 5.6, + "min": 2.7, + "max": 56.7, + "p25": 13.5, + "p75": 18.9, + "p85": 20.2, + "p95": 27.0 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 38.475, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 12, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_highland_arabica.json new file mode 100644 index 00000000000..473959c6abf --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_highland_arabica.json @@ -0,0 +1,3304 @@ +{ + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "durations": [ + 74.2, 56.7, 10.8, 85.1, 51.3, 29.7, 95.9, 40.5, 60.8, 24.3, 141.8, 47.2, + 16.2, 64.8, 52.7, 55.4, 59.4, 64.8, 68.9, 50.0, 54.0, 59.4, 63.5, 41.9, + 48.6, 54.0, 58.1, 36.5, 41.9, 62.1, 66.2, 44.6, 50.0, 52.7, 60.8, 39.2, + 44.6, 47.2, 51.3, 47.2, 52.7, 55.4, 59.4, 64.8, 47.2, 50.0, 54.0, 59.4, + 63.5, 44.6, 48.6, 54.0, 58.1, 36.5, 56.7, 62.1, 66.2, 44.6, 50.0 + ], + "observations": [ + { + "date": "2022-03-15", + "value": 74.2 + }, + { + "date": "2022-06-10", + "value": 56.7 + }, + { + "date": "2022-09-22", + "value": 10.8 + }, + { + "date": "2022-12-05", + "value": 85.1 + }, + { + "date": "2023-02-14", + "value": 51.3 + }, + { + "date": "2023-05-30", + "value": 29.7 + }, + { + "date": "2023-08-17", + "value": 95.9 + }, + { + "date": "2023-11-02", + "value": 40.5 + }, + { + "date": "2024-01-25", + "value": 60.8 + }, + { + "date": "2024-04-11", + "value": 24.3 + }, + { + "date": "2024-07-09", + "value": 141.8 + }, + { + "date": "2024-10-03", + "value": 47.2 + }, + { + "date": "2025-01-20", + "value": 16.2 + }, + { + "date": "2025-04-08", + "value": 64.8 + }, + { + "date": "2025-09-05", + "value": 52.7 + }, + { + "date": "2025-09-11", + "value": 55.4 + }, + { + "date": "2025-09-17", + "value": 59.4 + }, + { + "date": "2025-09-23", + "value": 64.8 + }, + { + "date": "2025-09-29", + "value": 68.9 + }, + { + "date": "2025-10-06", + "value": 50.0 + }, + { + "date": "2025-10-12", + "value": 54.0 + }, + { + "date": "2025-10-18", + "value": 59.4 + }, + { + "date": "2025-10-24", + "value": 63.5 + }, + { + "date": "2025-10-30", + "value": 41.9 + }, + { + "date": "2025-11-04", + "value": 48.6 + }, + { + "date": "2025-11-10", + "value": 54.0 + }, + { + "date": "2025-11-16", + "value": 58.1 + }, + { + "date": "2025-11-22", + "value": 36.5 + }, + { + "date": "2025-11-28", + "value": 41.9 + }, + { + "date": "2025-12-05", + "value": 62.1 + }, + { + "date": "2025-12-11", + "value": 66.2 + }, + { + "date": "2025-12-17", + "value": 44.6 + }, + { + "date": "2025-12-23", + "value": 50.0 + }, + { + "date": "2025-12-29", + "value": 52.7 + }, + { + "date": "2026-01-06", + "value": 60.8 + }, + { + "date": "2026-01-12", + "value": 39.2 + }, + { + "date": "2026-01-18", + "value": 44.6 + }, + { + "date": "2026-01-24", + "value": 47.2 + }, + { + "date": "2026-01-30", + "value": 51.3 + }, + { + "date": "2026-02-04", + "value": 47.2 + }, + { + "date": "2026-02-10", + "value": 52.7 + }, + { + "date": "2026-02-16", + "value": 55.4 + }, + { + "date": "2026-02-22", + "value": 59.4 + }, + { + "date": "2026-02-28", + "value": 64.8 + }, + { + "date": "2026-03-05", + "value": 47.2 + }, + { + "date": "2026-03-11", + "value": 50.0 + }, + { + "date": "2026-03-17", + "value": 54.0 + }, + { + "date": "2026-03-23", + "value": 59.4 + }, + { + "date": "2026-03-29", + "value": 63.5 + }, + { + "date": "2026-04-06", + "value": 44.6 + }, + { + "date": "2026-04-12", + "value": 48.6 + }, + { + "date": "2026-04-18", + "value": 54.0 + }, + { + "date": "2026-04-24", + "value": 58.1 + }, + { + "date": "2026-04-30", + "value": 36.5 + }, + { + "date": "2026-05-04", + "value": 56.7 + }, + { + "date": "2026-05-10", + "value": 62.1 + }, + { + "date": "2026-05-16", + "value": 66.2 + }, + { + "date": "2026-05-22", + "value": 44.6 + }, + { + "date": "2026-05-28", + "value": 50.0 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2022-06", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1 + }, + { + "month": "2022-09", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2022-12", + "mean": 85.1, + "median": 85.1, + "p10": 85.1, + "p25": 85.1, + "p75": 85.1, + "p90": 85.1, + "n": 1 + }, + { + "month": "2023-02", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2023-05", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2023-08", + "mean": 95.9, + "median": 95.9, + "p10": 95.9, + "p25": 95.9, + "p75": 95.9, + "p90": 95.9, + "n": 1 + }, + { + "month": "2023-11", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 60.8, + "median": 60.8, + "p10": 60.8, + "p25": 60.8, + "p75": 60.8, + "p90": 60.8, + "n": 1 + }, + { + "month": "2024-04", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 141.8, + "median": 141.8, + "p10": 141.8, + "p25": 141.8, + "p75": 141.8, + "p90": 141.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2025-09", + "mean": 60.2, + "median": 59.4, + "p10": 53.7, + "p25": 55.4, + "p75": 64.8, + "p90": 67.2, + "n": 5 + }, + { + "month": "2025-10", + "mean": 53.7, + "median": 54.0, + "p10": 45.1, + "p25": 50.0, + "p75": 59.4, + "p90": 61.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 47.8, + "median": 48.6, + "p10": 38.6, + "p25": 41.9, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2025-12", + "mean": 55.1, + "median": 52.7, + "p10": 46.7, + "p25": 50.0, + "p75": 62.1, + "p90": 64.5, + "n": 5 + }, + { + "month": "2026-01", + "mean": 48.6, + "median": 47.2, + "p10": 41.3, + "p25": 44.6, + "p75": 51.3, + "p90": 57.0, + "n": 5 + }, + { + "month": "2026-02", + "mean": 55.9, + "median": 55.4, + "p10": 49.4, + "p25": 52.7, + "p75": 59.4, + "p90": 62.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 54.8, + "median": 54.0, + "p10": 48.3, + "p25": 50.0, + "p75": 59.4, + "p90": 61.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 48.3, + "median": 48.6, + "p10": 39.7, + "p25": 44.6, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-05", + "mean": 55.9, + "median": 56.7, + "p10": 46.7, + "p25": 50.0, + "p75": 62.1, + "p90": 64.5, + "n": 5 + } + ], + "stats": { + "n": 59, + "mean": 54.3, + "median": 54.0, + "std": 13.3, + "min": 10.8, + "max": 141.8, + "p25": 47.2, + "p75": 60.8, + "p85": 64.8, + "p95": 74.2 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_highland_arabica", + "po_number": "4500000003", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000003", + "first_gr_date": "2025-06-03", + "days_vs_promised": -2, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000000", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000000", + "first_gr_date": "2025-06-06", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000005", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000005", + "first_gr_date": "2025-06-13", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000001", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000001", + "first_gr_date": "2025-06-15", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000002", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000002", + "first_gr_date": "2025-06-20", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000004", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000004", + "first_gr_date": "2025-06-21", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000006", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000006", + "first_gr_date": "2025-07-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000007", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000007", + "first_gr_date": "2025-07-10", + "days_vs_promised": 4, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000009", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000009", + "first_gr_date": "2025-07-21", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000010", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000010", + "first_gr_date": "2025-07-26", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000008", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000008", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000012", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000012", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000013", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000013", + "first_gr_date": "2025-08-20", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000014", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000014", + "first_gr_date": "2025-08-23", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000011", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000011", + "first_gr_date": "2025-08-25", + "days_vs_promised": 6, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000015", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000015", + "first_gr_date": "2025-08-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000016", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000016", + "first_gr_date": "2025-09-25", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000019", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000019", + "first_gr_date": "2025-09-27", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000020", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000020", + "first_gr_date": "2025-10-03", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000017", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000017", + "first_gr_date": "2025-10-05", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000018", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000018", + "first_gr_date": "2025-10-10", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000022", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000022", + "first_gr_date": "2025-10-16", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000021", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000021", + "first_gr_date": "2025-10-19", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000023", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000023", + "first_gr_date": "2025-10-31", + "days_vs_promised": 2, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000024", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000024", + "first_gr_date": "2025-11-01", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000025", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000025", + "first_gr_date": "2025-11-17", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000027", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000027", + "first_gr_date": "2025-11-29", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000028", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000028", + "first_gr_date": "2025-12-03", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000026", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000026", + "first_gr_date": "2025-12-04", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000029", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000029", + "first_gr_date": "2025-12-19", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000030", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000030", + "first_gr_date": "2025-12-24", + "days_vs_promised": 1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000034", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000034", + "first_gr_date": "2026-01-11", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000031", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000031", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000033", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000033", + "first_gr_date": "2026-01-13", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000035", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000035", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000032", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000032", + "first_gr_date": "2026-01-17", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000036", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000036", + "first_gr_date": "2026-01-31", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000037", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000037", + "first_gr_date": "2026-02-08", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000038", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000038", + "first_gr_date": "2026-02-11", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000040", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000040", + "first_gr_date": "2026-02-25", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000039", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000039", + "first_gr_date": "2026-03-01", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000041", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000041", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000042", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000042", + "first_gr_date": "2026-03-18", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000043", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000043", + "first_gr_date": "2026-03-22", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000044", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000044", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000045", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000045", + "first_gr_date": "2026-03-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000057", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000057", + "first_gr_date": "2026-04-01", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000068", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000068", + "first_gr_date": "2026-04-07", + "days_vs_promised": 4, + "lead_time_days": 42 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000069", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000069", + "first_gr_date": "2026-04-09", + "days_vs_promised": 3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000056", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000056", + "first_gr_date": "2026-04-10", + "days_vs_promised": 1, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000058", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000058", + "first_gr_date": "2026-04-12", + "days_vs_promised": 5, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000071", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000071", + "first_gr_date": "2026-04-13", + "days_vs_promised": -3, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000060", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000060", + "first_gr_date": "2026-04-14", + "days_vs_promised": 1, + "lead_time_days": 21 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000048", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000048", + "first_gr_date": "2026-04-22", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000050", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000050", + "first_gr_date": "2026-04-27", + "days_vs_promised": -3, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000046", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000046", + "first_gr_date": "2026-04-29", + "days_vs_promised": 3, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000047", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000047", + "first_gr_date": "2026-05-01", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000059", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000059", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000049", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000049", + "first_gr_date": "2026-05-06", + "days_vs_promised": -3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000074", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000074", + "first_gr_date": "2026-05-06", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000063", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000063", + "first_gr_date": "2026-05-07", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000051", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000051", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000070", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000070", + "first_gr_date": "2026-05-12", + "days_vs_promised": 20, + "lead_time_days": 64 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000075", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000075", + "first_gr_date": "2026-05-15", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000061", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000061", + "first_gr_date": "2026-05-18", + "days_vs_promised": -3, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000065", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000065", + "first_gr_date": "2026-05-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000072", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000072", + "first_gr_date": "2026-05-21", + "days_vs_promised": 18, + "lead_time_days": 58 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000062", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000062", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000053", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000053", + "first_gr_date": "2026-05-29", + "days_vs_promised": 0, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000077", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000077", + "first_gr_date": "2026-06-02", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000078", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000078", + "first_gr_date": "2026-06-03", + "days_vs_promised": -3, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000076", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000076", + "first_gr_date": "2026-06-04", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000064", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000064", + "first_gr_date": "2026-06-05", + "days_vs_promised": -1, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000052", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000052", + "first_gr_date": "2026-06-06", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000073", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000073", + "first_gr_date": "2026-06-07", + "days_vs_promised": 30, + "lead_time_days": 68 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000079", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000079", + "first_gr_date": "2026-06-09", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000054", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000054", + "first_gr_date": "2026-06-13", + "days_vs_promised": 0, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000055", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000055", + "first_gr_date": "2026-06-13", + "days_vs_promised": -2, + "lead_time_days": 33 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000066", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000066", + "first_gr_date": "2026-06-16", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000067", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000067", + "first_gr_date": "2026-06-22", + "days_vs_promised": 18, + "lead_time_days": 39 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 14, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0002", + "name": "Cascadia Coffee Traders" + }, + "vendors": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "n_lines": 56, + "n_late": 5, + "on_time_pct": 91.1, + "in_full_pct": 100.0, + "otif_pct": 91.1, + "mean_days_late_all": 0.29, + "mean_days_late_when_late": 3.2, + "median_days_late_when_late": 3, + "max_days_late": 6, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 8.9, + "ge_3d_pct": 5.4, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 12, + "n_late": 4, + "on_time_pct": 66.7, + "in_full_pct": 100.0, + "otif_pct": 66.7, + "mean_days_late_all": 2.08, + "mean_days_late_when_late": 6.2, + "median_days_late_when_late": 3.0, + "max_days_late": 18, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 33.3, + "ge_3d_pct": 16.7, + "ge_7d_pct": 8.3, + "ge_14d_pct": 8.3 + } + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "n_lines": 12, + "n_late": 5, + "on_time_pct": 58.3, + "in_full_pct": 100.0, + "otif_pct": 58.3, + "mean_days_late_all": 6.25, + "mean_days_late_when_late": 15, + "median_days_late_when_late": 18, + "max_days_late": 30, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 41.7, + "ge_3d_pct": 41.7, + "ge_7d_pct": 25.0, + "ge_14d_pct": 25.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 80, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000000", + "po_item": "00010", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "first_gr_date": "2025-06-06", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000001", + "po_item": "00020", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "first_gr_date": "2025-06-15", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000002", + "po_item": "00030", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "first_gr_date": "2025-06-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000003", + "po_item": "00040", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "first_gr_date": "2025-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000004", + "po_item": "00050", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "first_gr_date": "2025-06-21", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000005", + "po_item": "00010", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "first_gr_date": "2025-06-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000006", + "po_item": "00020", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "first_gr_date": "2025-07-09", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000008", + "po_item": "00040", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000009", + "po_item": "00050", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "first_gr_date": "2025-07-21", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000010", + "po_item": "00010", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "first_gr_date": "2025-07-26", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000012", + "po_item": "00030", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000013", + "po_item": "00040", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "first_gr_date": "2025-08-20", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000014", + "po_item": "00050", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "first_gr_date": "2025-08-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000015", + "po_item": "00010", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "first_gr_date": "2025-08-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000016", + "po_item": "00020", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "first_gr_date": "2025-09-25", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000017", + "po_item": "00030", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "first_gr_date": "2025-10-05", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000018", + "po_item": "00040", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "first_gr_date": "2025-10-10", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000019", + "po_item": "00050", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "first_gr_date": "2025-09-27", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000020", + "po_item": "00010", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "first_gr_date": "2025-10-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000021", + "po_item": "00020", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "first_gr_date": "2025-10-19", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000022", + "po_item": "00030", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "first_gr_date": "2025-10-16", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000023", + "po_item": "00040", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-31", + "days_late": 2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000024", + "po_item": "00050", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "first_gr_date": "2025-11-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000025", + "po_item": "00010", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "first_gr_date": "2025-11-17", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000026", + "po_item": "00020", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "first_gr_date": "2025-12-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000027", + "po_item": "00030", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "first_gr_date": "2025-11-29", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000028", + "po_item": "00040", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "first_gr_date": "2025-12-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000029", + "po_item": "00050", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "first_gr_date": "2025-12-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000030", + "po_item": "00010", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-24", + "days_late": 1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000031", + "po_item": "00020", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000032", + "po_item": "00030", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "first_gr_date": "2026-01-17", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000033", + "po_item": "00040", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000034", + "po_item": "00050", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000035", + "po_item": "00010", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000036", + "po_item": "00020", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "first_gr_date": "2026-01-31", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000037", + "po_item": "00030", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "first_gr_date": "2026-02-08", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000038", + "po_item": "00040", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000039", + "po_item": "00050", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "first_gr_date": "2026-03-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000040", + "po_item": "00010", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "first_gr_date": "2026-02-25", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000041", + "po_item": "00020", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000042", + "po_item": "00030", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "first_gr_date": "2026-03-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000043", + "po_item": "00040", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "first_gr_date": "2026-03-22", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000044", + "po_item": "00050", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000045", + "po_item": "00010", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000047", + "po_item": "00030", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-01", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000048", + "po_item": "00040", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "first_gr_date": "2026-04-22", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000049", + "po_item": "00050", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "first_gr_date": "2026-05-06", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000050", + "po_item": "00010", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "first_gr_date": "2026-04-27", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000051", + "po_item": "00020", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000052", + "po_item": "00030", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000053", + "po_item": "00040", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-29", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000054", + "po_item": "00050", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "first_gr_date": "2026-06-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000055", + "po_item": "00010", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "first_gr_date": "2026-06-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000056", + "po_item": "00010", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "first_gr_date": "2026-04-10", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000057", + "po_item": "00020", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "first_gr_date": "2026-04-01", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000059", + "po_item": "00040", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000060", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-14", + "days_late": 1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000061", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-18", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000062", + "po_item": "00020", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000063", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "first_gr_date": "2026-05-07", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000064", + "po_item": "00040", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-05", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000065", + "po_item": "00050", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "first_gr_date": "2026-05-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000066", + "po_item": "00010", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000071", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000074", + "po_item": "00020", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "first_gr_date": "2026-05-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000075", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-15", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000076", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000077", + "po_item": "00050", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "first_gr_date": "2026-06-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000078", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-03", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000079", + "po_item": "00020", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "first_gr_date": "2026-06-09", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_lowland_robusta.json new file mode 100644 index 00000000000..1e265cb23cb --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_lowland_robusta.json @@ -0,0 +1,2575 @@ +{ + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "durations": [ + 43.2, 64.8, 6.8, 90.5, 33.8, 55.4, 20.2, 110.7, 51.3, 27.0, 70.2, 13.5, + 59.4, 37.8, 47.2, 24.3, 74.2, 35.1, 35.1, 39.2, 41.9, 45.9, 50.0, 35.1, + 37.8, 41.9, 44.6, 48.6, 44.6, 48.6, 51.3, 56.7, 37.8, 43.2, 47.2, 51.3, + 32.4, 37.8, 54.0, 58.1, 39.2, 44.6, 47.2, 54.0, 35.1, 39.2, 41.9, 45.9, + 29.7, 35.1, 37.8, 41.9, 44.6, 41.9, 44.6, 48.6, 51.3, 56.7, 40.5, 43.2, + 47.2, 51.3, 32.4 + ], + "observations": [ + { + "date": "2022-02-08", + "value": 43.2 + }, + { + "date": "2022-04-19", + "value": 64.8 + }, + { + "date": "2022-07-11", + "value": 6.8 + }, + { + "date": "2022-09-28", + "value": 90.5 + }, + { + "date": "2022-12-15", + "value": 33.8 + }, + { + "date": "2023-03-07", + "value": 55.4 + }, + { + "date": "2023-05-22", + "value": 20.2 + }, + { + "date": "2023-08-09", + "value": 110.7 + }, + { + "date": "2023-10-30", + "value": 51.3 + }, + { + "date": "2024-01-16", + "value": 27.0 + }, + { + "date": "2024-03-25", + "value": 70.2 + }, + { + "date": "2024-06-12", + "value": 13.5 + }, + { + "date": "2024-08-28", + "value": 59.4 + }, + { + "date": "2024-11-14", + "value": 37.8 + }, + { + "date": "2025-01-06", + "value": 47.2 + }, + { + "date": "2025-03-18", + "value": 24.3 + }, + { + "date": "2025-05-29", + "value": 74.2 + }, + { + "date": "2025-08-12", + "value": 35.1 + }, + { + "date": "2025-09-04", + "value": 35.1 + }, + { + "date": "2025-09-10", + "value": 39.2 + }, + { + "date": "2025-09-16", + "value": 41.9 + }, + { + "date": "2025-09-22", + "value": 45.9 + }, + { + "date": "2025-09-28", + "value": 50.0 + }, + { + "date": "2025-10-05", + "value": 35.1 + }, + { + "date": "2025-10-11", + "value": 37.8 + }, + { + "date": "2025-10-17", + "value": 41.9 + }, + { + "date": "2025-10-23", + "value": 44.6 + }, + { + "date": "2025-10-29", + "value": 48.6 + }, + { + "date": "2025-11-06", + "value": 44.6 + }, + { + "date": "2025-11-12", + "value": 48.6 + }, + { + "date": "2025-11-18", + "value": 51.3 + }, + { + "date": "2025-11-24", + "value": 56.7 + }, + { + "date": "2025-11-30", + "value": 37.8 + }, + { + "date": "2025-12-04", + "value": 43.2 + }, + { + "date": "2025-12-10", + "value": 47.2 + }, + { + "date": "2025-12-16", + "value": 51.3 + }, + { + "date": "2025-12-22", + "value": 32.4 + }, + { + "date": "2025-12-28", + "value": 37.8 + }, + { + "date": "2026-01-05", + "value": 54.0 + }, + { + "date": "2026-01-11", + "value": 58.1 + }, + { + "date": "2026-01-17", + "value": 39.2 + }, + { + "date": "2026-01-23", + "value": 44.6 + }, + { + "date": "2026-01-29", + "value": 47.2 + }, + { + "date": "2026-02-06", + "value": 54.0 + }, + { + "date": "2026-02-12", + "value": 35.1 + }, + { + "date": "2026-02-18", + "value": 39.2 + }, + { + "date": "2026-02-24", + "value": 41.9 + }, + { + "date": "2026-02-30", + "value": 45.9 + }, + { + "date": "2026-03-04", + "value": 29.7 + }, + { + "date": "2026-03-10", + "value": 35.1 + }, + { + "date": "2026-03-16", + "value": 37.8 + }, + { + "date": "2026-03-22", + "value": 41.9 + }, + { + "date": "2026-03-28", + "value": 44.6 + }, + { + "date": "2026-04-05", + "value": 41.9 + }, + { + "date": "2026-04-11", + "value": 44.6 + }, + { + "date": "2026-04-17", + "value": 48.6 + }, + { + "date": "2026-04-23", + "value": 51.3 + }, + { + "date": "2026-04-29", + "value": 56.7 + }, + { + "date": "2026-05-06", + "value": 40.5 + }, + { + "date": "2026-05-12", + "value": 43.2 + }, + { + "date": "2026-05-18", + "value": 47.2 + }, + { + "date": "2026-05-24", + "value": 51.3 + }, + { + "date": "2026-05-30", + "value": 32.4 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 43.2, + "median": 43.2, + "p10": 43.2, + "p25": 43.2, + "p75": 43.2, + "p90": 43.2, + "n": 1 + }, + { + "month": "2022-04", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2022-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-09", + "mean": 90.5, + "median": 90.5, + "p10": 90.5, + "p25": 90.5, + "p75": 90.5, + "p90": 90.5, + "n": 1 + }, + { + "month": "2022-12", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2023-03", + "mean": 55.4, + "median": 55.4, + "p10": 55.4, + "p25": 55.4, + "p75": 55.4, + "p90": 55.4, + "n": 1 + }, + { + "month": "2023-05", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2023-08", + "mean": 110.7, + "median": 110.7, + "p10": 110.7, + "p25": 110.7, + "p75": 110.7, + "p90": 110.7, + "n": 1 + }, + { + "month": "2023-10", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-01", + "mean": 27.0, + "median": 27.0, + "p10": 27.0, + "p25": 27.0, + "p75": 27.0, + "p90": 27.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 70.2, + "median": 70.2, + "p10": 70.2, + "p25": 70.2, + "p75": 70.2, + "p90": 70.2, + "n": 1 + }, + { + "month": "2024-06", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 59.4, + "median": 59.4, + "p10": 59.4, + "p25": 59.4, + "p75": 59.4, + "p90": 59.4, + "n": 1 + }, + { + "month": "2024-11", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-01", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2025-03", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2025-05", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 35.1, + "median": 35.1, + "p10": 35.1, + "p25": 35.1, + "p75": 35.1, + "p90": 35.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 42.4, + "median": 41.9, + "p10": 36.7, + "p25": 39.2, + "p75": 45.9, + "p90": 48.3, + "n": 5 + }, + { + "month": "2025-10", + "mean": 41.6, + "median": 41.9, + "p10": 36.2, + "p25": 37.8, + "p75": 44.6, + "p90": 47.0, + "n": 5 + }, + { + "month": "2025-11", + "mean": 47.8, + "median": 48.6, + "p10": 40.5, + "p25": 44.6, + "p75": 51.3, + "p90": 54.5, + "n": 5 + }, + { + "month": "2025-12", + "mean": 42.4, + "median": 43.2, + "p10": 34.6, + "p25": 37.8, + "p75": 47.2, + "p90": 49.7, + "n": 5 + }, + { + "month": "2026-01", + "mean": 48.6, + "median": 47.2, + "p10": 41.3, + "p25": 44.6, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-02", + "mean": 43.2, + "median": 41.9, + "p10": 36.7, + "p25": 39.2, + "p75": 45.9, + "p90": 50.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 37.8, + "median": 37.8, + "p10": 31.9, + "p25": 35.1, + "p75": 41.9, + "p90": 43.5, + "n": 5 + }, + { + "month": "2026-04", + "mean": 48.6, + "median": 48.6, + "p10": 42.9, + "p25": 44.6, + "p75": 51.3, + "p90": 54.5, + "n": 5 + }, + { + "month": "2026-05", + "mean": 42.9, + "median": 43.2, + "p10": 35.6, + "p25": 40.5, + "p75": 47.2, + "p90": 49.7, + "n": 5 + } + ], + "stats": { + "n": 63, + "mean": 45.1, + "median": 44.6, + "std": 11.4, + "min": 6.8, + "max": 110.7, + "p25": 37.8, + "p75": 51.3, + "p85": 54.0, + "p95": 64.8 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000081", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000081", + "first_gr_date": "2025-08-29", + "days_vs_promised": -1, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000082", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000082", + "first_gr_date": "2025-09-03", + "days_vs_promised": -2, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000080", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000080", + "first_gr_date": "2025-09-08", + "days_vs_promised": -2, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000083", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000083", + "first_gr_date": "2025-09-16", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000084", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000084", + "first_gr_date": "2025-10-01", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000086", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000086", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000088", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000088", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000085", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000085", + "first_gr_date": "2025-10-19", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000087", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000087", + "first_gr_date": "2025-10-22", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000089", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000089", + "first_gr_date": "2025-11-01", + "days_vs_promised": -1, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000090", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000090", + "first_gr_date": "2025-11-06", + "days_vs_promised": -1, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000093", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000093", + "first_gr_date": "2025-11-23", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000094", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000094", + "first_gr_date": "2025-11-25", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000091", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000091", + "first_gr_date": "2025-11-30", + "days_vs_promised": -2, + "lead_time_days": 47 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000092", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000092", + "first_gr_date": "2025-12-07", + "days_vs_promised": -1, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000095", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000095", + "first_gr_date": "2025-12-20", + "days_vs_promised": -3, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000099", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000099", + "first_gr_date": "2025-12-27", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000096", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000096", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000098", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000098", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000097", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000097", + "first_gr_date": "2025-12-30", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000101", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000101", + "first_gr_date": "2026-01-15", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000102", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000102", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000100", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000100", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000122", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000122", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000104", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000104", + "first_gr_date": "2026-02-08", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000103", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000103", + "first_gr_date": "2026-02-13", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000105", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000105", + "first_gr_date": "2026-02-23", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000125", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000125", + "first_gr_date": "2026-02-24", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000123", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000123", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000107", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000107", + "first_gr_date": "2026-03-02", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000124", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000124", + "first_gr_date": "2026-03-07", + "days_vs_promised": -3, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000106", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000106", + "first_gr_date": "2026-03-13", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000126", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000126", + "first_gr_date": "2026-03-14", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000127", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000127", + "first_gr_date": "2026-03-23", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000108", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000108", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000128", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000128", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000110", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000110", + "first_gr_date": "2026-03-25", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000109", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000109", + "first_gr_date": "2026-04-06", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000129", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000129", + "first_gr_date": "2026-04-08", + "days_vs_promised": -3, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000114", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000114", + "first_gr_date": "2026-04-11", + "days_vs_promised": -2, + "lead_time_days": 19 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000111", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000111", + "first_gr_date": "2026-04-12", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000112", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000112", + "first_gr_date": "2026-04-13", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000130", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000130", + "first_gr_date": "2026-04-17", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000115", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000115", + "first_gr_date": "2026-04-23", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000134", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000134", + "first_gr_date": "2026-04-30", + "days_vs_promised": -3, + "lead_time_days": 24 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000113", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000113", + "first_gr_date": "2026-05-01", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000131", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000131", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000117", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000117", + "first_gr_date": "2026-05-05", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000136", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000136", + "first_gr_date": "2026-05-08", + "days_vs_promised": -2, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000132", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000132", + "first_gr_date": "2026-05-09", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000133", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000133", + "first_gr_date": "2026-05-13", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000135", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000135", + "first_gr_date": "2026-05-18", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000116", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000116", + "first_gr_date": "2026-05-21", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000138", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000138", + "first_gr_date": "2026-05-28", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000118", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000118", + "first_gr_date": "2026-05-31", + "days_vs_promised": -1, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000139", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000139", + "first_gr_date": "2026-05-31", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000137", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000137", + "first_gr_date": "2026-06-01", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000120", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000120", + "first_gr_date": "2026-06-05", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000119", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000119", + "first_gr_date": "2026-06-17", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000121", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000121", + "first_gr_date": "2026-06-19", + "days_vs_promised": 0, + "lead_time_days": 37 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 18, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0004", + "name": "Riverbend Reliable Supply" + }, + "vendors": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "n_lines": 42, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "n_lines": 18, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [], + "coverage_pct": 100.0, + "n_lines": 60, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000080", + "po_item": "00010", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "first_gr_date": "2025-09-08", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000081", + "po_item": "00020", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "first_gr_date": "2025-08-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000082", + "po_item": "00030", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "first_gr_date": "2025-09-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000083", + "po_item": "00040", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "first_gr_date": "2025-09-16", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000084", + "po_item": "00050", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "first_gr_date": "2025-10-01", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000085", + "po_item": "00010", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "first_gr_date": "2025-10-19", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000086", + "po_item": "00020", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000087", + "po_item": "00030", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "first_gr_date": "2025-10-22", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000088", + "po_item": "00040", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000089", + "po_item": "00050", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-01", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000090", + "po_item": "00010", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-06", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000091", + "po_item": "00020", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "first_gr_date": "2025-11-30", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000092", + "po_item": "00030", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "first_gr_date": "2025-12-07", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000093", + "po_item": "00040", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "first_gr_date": "2025-11-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000094", + "po_item": "00050", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "first_gr_date": "2025-11-25", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000095", + "po_item": "00010", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-20", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000096", + "po_item": "00020", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000097", + "po_item": "00030", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "first_gr_date": "2025-12-30", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000098", + "po_item": "00040", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000099", + "po_item": "00050", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "first_gr_date": "2025-12-27", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000100", + "po_item": "00010", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000101", + "po_item": "00020", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000102", + "po_item": "00030", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000103", + "po_item": "00040", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-13", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000104", + "po_item": "00050", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "first_gr_date": "2026-02-08", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000105", + "po_item": "00010", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "first_gr_date": "2026-02-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000106", + "po_item": "00020", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "first_gr_date": "2026-03-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000107", + "po_item": "00030", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "first_gr_date": "2026-03-02", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000108", + "po_item": "00040", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000109", + "po_item": "00050", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000110", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-25", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000111", + "po_item": "00020", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "first_gr_date": "2026-04-12", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000112", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-13", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000113", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "first_gr_date": "2026-05-01", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000114", + "po_item": "00050", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-11", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000115", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "first_gr_date": "2026-04-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000116", + "po_item": "00020", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-21", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000117", + "po_item": "00030", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "first_gr_date": "2026-05-05", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000118", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "first_gr_date": "2026-05-31", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000119", + "po_item": "00050", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "first_gr_date": "2026-06-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000120", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "first_gr_date": "2026-06-05", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000121", + "po_item": "00020", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "first_gr_date": "2026-06-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000122", + "po_item": "00010", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000123", + "po_item": "00020", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000124", + "po_item": "00030", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-07", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000125", + "po_item": "00040", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "first_gr_date": "2026-02-24", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000126", + "po_item": "00050", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "first_gr_date": "2026-03-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000127", + "po_item": "00010", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-23", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000128", + "po_item": "00020", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000129", + "po_item": "00030", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-08", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000130", + "po_item": "00040", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "first_gr_date": "2026-04-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000131", + "po_item": "00050", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000132", + "po_item": "00010", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000133", + "po_item": "00020", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "first_gr_date": "2026-05-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000134", + "po_item": "00030", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "first_gr_date": "2026-04-30", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000135", + "po_item": "00040", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000136", + "po_item": "00050", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "first_gr_date": "2026-05-08", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000137", + "po_item": "00010", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "first_gr_date": "2026-06-01", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000138", + "po_item": "00020", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "first_gr_date": "2026-05-28", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000139", + "po_item": "00030", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "first_gr_date": "2026-05-31", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_washed_bourbon.json new file mode 100644 index 00000000000..11dafb65743 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/procurement_washed_bourbon.json @@ -0,0 +1,2251 @@ +{ + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "durations": [ + 47.2, 21.6, 83.7, 9.5, 54.0, 33.8, 64.8, 16.2, 40.5, 18.9, 40.5, 25.7, 29.7, + 31.1, 33.8, 31.1, 33.8, 36.5, 39.2, 41.9, 31.1, 33.8, 36.5, 39.2, 41.9, + 29.7, 32.4, 35.1, 37.8, 24.3, 37.8, 40.5, 43.2, 29.7, 32.4, 36.5, 40.5, + 25.7, 29.7, 31.1, 45.9, 31.1, 33.8, 36.5, 39.2, 27.0, 31.1, 33.8, 36.5, + 39.2, 27.0, 29.7, 32.4, 35.1, 37.8 + ], + "observations": [ + { + "date": "2022-05-03", + "value": 47.2 + }, + { + "date": "2022-10-18", + "value": 21.6 + }, + { + "date": "2023-01-24", + "value": 83.7 + }, + { + "date": "2023-06-15", + "value": 9.5 + }, + { + "date": "2023-09-28", + "value": 54.0 + }, + { + "date": "2024-02-12", + "value": 33.8 + }, + { + "date": "2024-05-07", + "value": 64.8 + }, + { + "date": "2024-09-19", + "value": 16.2 + }, + { + "date": "2025-02-04", + "value": 40.5 + }, + { + "date": "2025-06-10", + "value": 18.9 + }, + { + "date": "2025-09-06", + "value": 40.5 + }, + { + "date": "2025-09-12", + "value": 25.7 + }, + { + "date": "2025-09-18", + "value": 29.7 + }, + { + "date": "2025-09-24", + "value": 31.1 + }, + { + "date": "2025-09-30", + "value": 33.8 + }, + { + "date": "2025-10-04", + "value": 31.1 + }, + { + "date": "2025-10-10", + "value": 33.8 + }, + { + "date": "2025-10-16", + "value": 36.5 + }, + { + "date": "2025-10-22", + "value": 39.2 + }, + { + "date": "2025-10-28", + "value": 41.9 + }, + { + "date": "2025-11-05", + "value": 31.1 + }, + { + "date": "2025-11-11", + "value": 33.8 + }, + { + "date": "2025-11-17", + "value": 36.5 + }, + { + "date": "2025-11-23", + "value": 39.2 + }, + { + "date": "2025-11-29", + "value": 41.9 + }, + { + "date": "2025-12-06", + "value": 29.7 + }, + { + "date": "2025-12-12", + "value": 32.4 + }, + { + "date": "2025-12-18", + "value": 35.1 + }, + { + "date": "2025-12-24", + "value": 37.8 + }, + { + "date": "2025-12-30", + "value": 24.3 + }, + { + "date": "2026-01-04", + "value": 37.8 + }, + { + "date": "2026-01-10", + "value": 40.5 + }, + { + "date": "2026-01-16", + "value": 43.2 + }, + { + "date": "2026-01-22", + "value": 29.7 + }, + { + "date": "2026-01-28", + "value": 32.4 + }, + { + "date": "2026-02-05", + "value": 36.5 + }, + { + "date": "2026-02-11", + "value": 40.5 + }, + { + "date": "2026-02-17", + "value": 25.7 + }, + { + "date": "2026-02-23", + "value": 29.7 + }, + { + "date": "2026-02-29", + "value": 31.1 + }, + { + "date": "2026-03-06", + "value": 45.9 + }, + { + "date": "2026-03-12", + "value": 31.1 + }, + { + "date": "2026-03-18", + "value": 33.8 + }, + { + "date": "2026-03-24", + "value": 36.5 + }, + { + "date": "2026-03-30", + "value": 39.2 + }, + { + "date": "2026-04-04", + "value": 27.0 + }, + { + "date": "2026-04-10", + "value": 31.1 + }, + { + "date": "2026-04-16", + "value": 33.8 + }, + { + "date": "2026-04-22", + "value": 36.5 + }, + { + "date": "2026-04-28", + "value": 39.2 + }, + { + "date": "2026-05-05", + "value": 27.0 + }, + { + "date": "2026-05-11", + "value": 29.7 + }, + { + "date": "2026-05-17", + "value": 32.4 + }, + { + "date": "2026-05-23", + "value": 35.1 + }, + { + "date": "2026-05-29", + "value": 37.8 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 21.6, + "median": 21.6, + "p10": 21.6, + "p25": 21.6, + "p75": 21.6, + "p90": 21.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 83.7, + "median": 83.7, + "p10": 83.7, + "p25": 83.7, + "p75": 83.7, + "p90": 83.7, + "n": 1 + }, + { + "month": "2023-06", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 54.0, + "median": 54.0, + "p10": 54.0, + "p25": 54.0, + "p75": 54.0, + "p90": 54.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-05", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2025-02", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2025-06", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 32.1, + "median": 31.1, + "p10": 27.3, + "p25": 29.7, + "p75": 33.8, + "p90": 37.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 36.5, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 36.5, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 31.9, + "median": 32.4, + "p10": 26.5, + "p25": 29.7, + "p75": 35.1, + "p90": 36.7, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.7, + "median": 37.8, + "p10": 30.8, + "p25": 32.4, + "p75": 40.5, + "p90": 42.1, + "n": 5 + }, + { + "month": "2026-02", + "mean": 32.7, + "median": 31.1, + "p10": 27.3, + "p25": 29.7, + "p75": 36.5, + "p90": 38.9, + "n": 5 + }, + { + "month": "2026-03", + "mean": 37.3, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 43.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 33.5, + "median": 33.8, + "p10": 28.6, + "p25": 31.1, + "p75": 36.5, + "p90": 38.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 32.4, + "median": 32.4, + "p10": 28.1, + "p25": 29.7, + "p75": 35.1, + "p90": 36.7, + "n": 5 + } + ], + "stats": { + "n": 55, + "mean": 35.2, + "median": 33.8, + "std": 8.0, + "min": 9.5, + "max": 83.7, + "p25": 29.7, + "p75": 39.2, + "p85": 40.5, + "p95": 47.2 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000142", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000142", + "first_gr_date": "2025-10-29", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000141", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000141", + "first_gr_date": "2025-11-02", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000140", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000140", + "first_gr_date": "2025-11-07", + "days_vs_promised": 24, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000143", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000143", + "first_gr_date": "2025-11-07", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000144", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000144", + "first_gr_date": "2025-11-10", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000146", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000146", + "first_gr_date": "2025-12-03", + "days_vs_promised": -2, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000145", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000145", + "first_gr_date": "2025-12-11", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000148", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000148", + "first_gr_date": "2025-12-21", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000147", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000147", + "first_gr_date": "2025-12-23", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000150", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000150", + "first_gr_date": "2026-01-06", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000149", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000149", + "first_gr_date": "2026-01-07", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000151", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000151", + "first_gr_date": "2026-01-13", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000153", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000153", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000155", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000155", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000152", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000152", + "first_gr_date": "2026-01-26", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000154", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000154", + "first_gr_date": "2026-01-31", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000156", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000156", + "first_gr_date": "2026-02-14", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000158", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000158", + "first_gr_date": "2026-02-15", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000157", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000157", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000159", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000159", + "first_gr_date": "2026-03-06", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000176", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000176", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000160", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000160", + "first_gr_date": "2026-03-08", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000175", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000175", + "first_gr_date": "2026-03-10", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000178", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000178", + "first_gr_date": "2026-03-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000161", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000161", + "first_gr_date": "2026-03-20", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000179", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000179", + "first_gr_date": "2026-03-29", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000162", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000162", + "first_gr_date": "2026-04-01", + "days_vs_promised": 12, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000180", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000180", + "first_gr_date": "2026-04-02", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000177", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000177", + "first_gr_date": "2026-04-05", + "days_vs_promised": 2, + "lead_time_days": 47 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000165", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000165", + "first_gr_date": "2026-04-07", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000164", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000164", + "first_gr_date": "2026-04-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000163", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000163", + "first_gr_date": "2026-04-10", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000166", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000166", + "first_gr_date": "2026-04-10", + "days_vs_promised": -1, + "lead_time_days": 24 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000167", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000167", + "first_gr_date": "2026-04-16", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000181", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000181", + "first_gr_date": "2026-04-24", + "days_vs_promised": 0, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000182", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000182", + "first_gr_date": "2026-04-25", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000183", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000183", + "first_gr_date": "2026-04-26", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000168", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000168", + "first_gr_date": "2026-04-30", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000171", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000171", + "first_gr_date": "2026-05-11", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000185", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000185", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000184", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000184", + "first_gr_date": "2026-05-16", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000169", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000169", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000170", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000170", + "first_gr_date": "2026-05-27", + "days_vs_promised": -2, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000174", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000174", + "first_gr_date": "2026-06-03", + "days_vs_promised": -2, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000172", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000172", + "first_gr_date": "2026-06-09", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000186", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000186", + "first_gr_date": "2026-06-15", + "days_vs_promised": 5, + "lead_time_days": 55 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000189", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000189", + "first_gr_date": "2026-06-17", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000187", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000187", + "first_gr_date": "2026-06-18", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000188", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000188", + "first_gr_date": "2026-06-21", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000173", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000173", + "first_gr_date": "2026-07-02", + "days_vs_promised": 8, + "lead_time_days": 58 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0005", + "name": "Midland Mid-Tier Partners" + }, + "vendors": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "n_lines": 35, + "n_late": 4, + "on_time_pct": 88.6, + "in_full_pct": 100.0, + "otif_pct": 88.6, + "mean_days_late_all": 1.29, + "mean_days_late_when_late": 11.2, + "median_days_late_when_late": 10.0, + "max_days_late": 24, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 11.4, + "ge_3d_pct": 8.6, + "ge_7d_pct": 8.6, + "ge_14d_pct": 2.9 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 15, + "n_late": 3, + "on_time_pct": 80.0, + "in_full_pct": 100.0, + "otif_pct": 80.0, + "mean_days_late_all": 0.53, + "mean_days_late_when_late": 2.7, + "median_days_late_when_late": 2, + "max_days_late": 5, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 20.0, + "ge_3d_pct": 6.7, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 50, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000141", + "po_item": "00020", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000142", + "po_item": "00030", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-29", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000143", + "po_item": "00040", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000144", + "po_item": "00050", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "first_gr_date": "2025-11-10", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000145", + "po_item": "00010", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "first_gr_date": "2025-12-11", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000146", + "po_item": "00020", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "first_gr_date": "2025-12-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000147", + "po_item": "00030", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000148", + "po_item": "00040", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "first_gr_date": "2025-12-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000149", + "po_item": "00050", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "first_gr_date": "2026-01-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000150", + "po_item": "00010", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "first_gr_date": "2026-01-06", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000151", + "po_item": "00020", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "first_gr_date": "2026-01-13", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000152", + "po_item": "00030", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "first_gr_date": "2026-01-26", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000153", + "po_item": "00040", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000154", + "po_item": "00050", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "first_gr_date": "2026-01-31", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000155", + "po_item": "00010", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000156", + "po_item": "00020", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "first_gr_date": "2026-02-14", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000157", + "po_item": "00030", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000158", + "po_item": "00040", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "first_gr_date": "2026-02-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000159", + "po_item": "00050", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "first_gr_date": "2026-03-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000160", + "po_item": "00010", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "first_gr_date": "2026-03-08", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000163", + "po_item": "00040", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000164", + "po_item": "00050", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-09", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000165", + "po_item": "00010", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000166", + "po_item": "00020", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-10", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000167", + "po_item": "00030", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000168", + "po_item": "00040", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "first_gr_date": "2026-04-30", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000169", + "po_item": "00050", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000170", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-27", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000171", + "po_item": "00020", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "first_gr_date": "2026-05-11", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000172", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "first_gr_date": "2026-06-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000174", + "po_item": "00050", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "first_gr_date": "2026-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000175", + "po_item": "00010", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000176", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000178", + "po_item": "00040", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-19", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000179", + "po_item": "00050", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "first_gr_date": "2026-03-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000180", + "po_item": "00010", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "first_gr_date": "2026-04-02", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000181", + "po_item": "00020", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "first_gr_date": "2026-04-24", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000182", + "po_item": "00030", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "first_gr_date": "2026-04-25", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000183", + "po_item": "00040", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-26", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000184", + "po_item": "00050", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "first_gr_date": "2026-05-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000185", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000187", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "first_gr_date": "2026-06-18", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000188", + "po_item": "00040", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "first_gr_date": "2026-06-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_green_blend.json new file mode 100644 index 00000000000..5eb3ef59ad9 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_green_blend.json @@ -0,0 +1,924 @@ +{ + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "durations": [ + 4.1, 6.8, 2.7, 9.5, 5.4, 8.1, 4.1, 18.9, 5.4, 10.8, 4.1, 6.8, 1.4, 8.1, 4.1, + 5.4, 5.4, 5.4, 4.1, 5.4, 5.4, 5.4, 5.4, 6.8, 6.8, 6.8, 5.4, 6.8, 6.8, 4.1, + 5.4, 6.8, 4.1, 4.1, 6.8, 4.1, 5.4, 5.4, 4.1, 4.1, 5.4, 5.4, 5.4, 5.4, 6.8, + 6.8, 5.4, 5.4, 6.8, 6.8 + ], + "observations": [ + { + "date": "2022-04-18", + "value": 4.1 + }, + { + "date": "2022-07-05", + "value": 6.8 + }, + { + "date": "2022-10-12", + "value": 2.7 + }, + { + "date": "2023-01-20", + "value": 9.5 + }, + { + "date": "2023-04-15", + "value": 5.4 + }, + { + "date": "2023-07-28", + "value": 8.1 + }, + { + "date": "2023-10-05", + "value": 4.1 + }, + { + "date": "2024-01-12", + "value": 18.9 + }, + { + "date": "2024-04-22", + "value": 5.4 + }, + { + "date": "2024-07-10", + "value": 10.8 + }, + { + "date": "2024-10-18", + "value": 4.1 + }, + { + "date": "2025-01-25", + "value": 6.8 + }, + { + "date": "2025-05-08", + "value": 1.4 + }, + { + "date": "2025-08-15", + "value": 8.1 + }, + { + "date": "2025-09-04", + "value": 4.1 + }, + { + "date": "2025-09-10", + "value": 5.4 + }, + { + "date": "2025-09-16", + "value": 5.4 + }, + { + "date": "2025-09-22", + "value": 5.4 + }, + { + "date": "2025-10-05", + "value": 4.1 + }, + { + "date": "2025-10-11", + "value": 5.4 + }, + { + "date": "2025-10-17", + "value": 5.4 + }, + { + "date": "2025-10-23", + "value": 5.4 + }, + { + "date": "2025-11-06", + "value": 5.4 + }, + { + "date": "2025-11-12", + "value": 6.8 + }, + { + "date": "2025-11-18", + "value": 6.8 + }, + { + "date": "2025-11-24", + "value": 6.8 + }, + { + "date": "2025-12-04", + "value": 5.4 + }, + { + "date": "2025-12-10", + "value": 6.8 + }, + { + "date": "2025-12-16", + "value": 6.8 + }, + { + "date": "2025-12-22", + "value": 4.1 + }, + { + "date": "2026-01-05", + "value": 5.4 + }, + { + "date": "2026-01-11", + "value": 6.8 + }, + { + "date": "2026-01-17", + "value": 4.1 + }, + { + "date": "2026-01-23", + "value": 4.1 + }, + { + "date": "2026-02-06", + "value": 6.8 + }, + { + "date": "2026-02-12", + "value": 4.1 + }, + { + "date": "2026-02-18", + "value": 5.4 + }, + { + "date": "2026-02-24", + "value": 5.4 + }, + { + "date": "2026-03-04", + "value": 4.1 + }, + { + "date": "2026-03-10", + "value": 4.1 + }, + { + "date": "2026-03-16", + "value": 5.4 + }, + { + "date": "2026-03-22", + "value": 5.4 + }, + { + "date": "2026-04-05", + "value": 5.4 + }, + { + "date": "2026-04-11", + "value": 5.4 + }, + { + "date": "2026-04-17", + "value": 6.8 + }, + { + "date": "2026-04-23", + "value": 6.8 + }, + { + "date": "2026-05-06", + "value": 5.4 + }, + { + "date": "2026-05-12", + "value": 5.4 + }, + { + "date": "2026-05-18", + "value": 6.8 + }, + { + "date": "2026-05-24", + "value": 6.8 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-01", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-04", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-07", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2023-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2024-04", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-01", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-10", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 6.5, + "median": 6.8, + "p10": 5.8, + "p25": 6.5, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2025-12", + "mean": 5.8, + "median": 6.1, + "p10": 4.5, + "p25": 5.1, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2026-01", + "mean": 5.1, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.8, + "p90": 6.3, + "n": 4 + }, + { + "month": "2026-02", + "mean": 5.4, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.8, + "p90": 6.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 6.1, + "median": 6.1, + "p10": 5.4, + "p25": 5.4, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2026-05", + "mean": 6.1, + "median": 6.1, + "p10": 5.4, + "p25": 5.4, + "p75": 6.8, + "p90": 6.8, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 5.9, + "median": 5.4, + "std": 1.8, + "min": 1.4, + "max": 18.9, + "p25": 4.1, + "p75": 6.8, + "p85": 6.8, + "p95": 8.1 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 50, + "n_movements": null, + "yield_data": { + "values": [ + 98.2, 99.5, 97.8, 100.2, 96.5, 99.0, 98.8, 97.2, 99.5, 100.8, 98.0, 97.5, + 99.2, 98.5, 98.4, 98.6, 98.9, 99.1, 98.3, 98.5, 98.8, 99.1, 99.0, 99.3, + 99.6, 98.2, 99.0, 99.3, 97.9, 98.2, 98.9, 97.6, 97.9, 98.1, 98.1, 98.4, + 98.6, 98.9, 98.1, 98.3, 98.5, 98.8, 98.8, 99.0, 99.3, 99.6, 98.7, 99.0, + 99.3, 97.9 + ], + "observations": [ + { + "date": "2022-04-21", + "value": 98.2 + }, + { + "date": "2022-07-10", + "value": 99.5 + }, + { + "date": "2022-10-14", + "value": 97.8 + }, + { + "date": "2023-01-27", + "value": 100.2 + }, + { + "date": "2023-04-19", + "value": 96.5 + }, + { + "date": "2023-08-03", + "value": 99.0 + }, + { + "date": "2023-10-08", + "value": 98.8 + }, + { + "date": "2024-01-26", + "value": 97.2 + }, + { + "date": "2024-04-26", + "value": 99.5 + }, + { + "date": "2024-07-18", + "value": 100.8 + }, + { + "date": "2024-10-21", + "value": 98.0 + }, + { + "date": "2025-01-30", + "value": 97.5 + }, + { + "date": "2025-05-09", + "value": 99.2 + }, + { + "date": "2025-08-21", + "value": 98.5 + }, + { + "date": "2025-09-05", + "value": 98.4 + }, + { + "date": "2025-09-11", + "value": 98.6 + }, + { + "date": "2025-09-17", + "value": 98.9 + }, + { + "date": "2025-09-23", + "value": 99.1 + }, + { + "date": "2025-10-06", + "value": 98.3 + }, + { + "date": "2025-10-12", + "value": 98.5 + }, + { + "date": "2025-10-18", + "value": 98.8 + }, + { + "date": "2025-10-24", + "value": 99.1 + }, + { + "date": "2025-11-04", + "value": 99.0 + }, + { + "date": "2025-11-10", + "value": 99.3 + }, + { + "date": "2025-11-16", + "value": 99.6 + }, + { + "date": "2025-11-22", + "value": 98.2 + }, + { + "date": "2025-12-05", + "value": 99.0 + }, + { + "date": "2025-12-11", + "value": 99.3 + }, + { + "date": "2025-12-17", + "value": 97.9 + }, + { + "date": "2025-12-23", + "value": 98.2 + }, + { + "date": "2026-01-06", + "value": 98.9 + }, + { + "date": "2026-01-12", + "value": 97.6 + }, + { + "date": "2026-01-18", + "value": 97.9 + }, + { + "date": "2026-01-24", + "value": 98.1 + }, + { + "date": "2026-02-04", + "value": 98.1 + }, + { + "date": "2026-02-10", + "value": 98.4 + }, + { + "date": "2026-02-16", + "value": 98.6 + }, + { + "date": "2026-02-22", + "value": 98.9 + }, + { + "date": "2026-03-05", + "value": 98.1 + }, + { + "date": "2026-03-11", + "value": 98.3 + }, + { + "date": "2026-03-17", + "value": 98.5 + }, + { + "date": "2026-03-23", + "value": 98.8 + }, + { + "date": "2026-04-06", + "value": 98.8 + }, + { + "date": "2026-04-12", + "value": 99.0 + }, + { + "date": "2026-04-18", + "value": 99.3 + }, + { + "date": "2026-04-24", + "value": 99.6 + }, + { + "date": "2026-05-04", + "value": 98.7 + }, + { + "date": "2026-05-10", + "value": 99.0 + }, + { + "date": "2026-05-16", + "value": 99.3 + }, + { + "date": "2026-05-22", + "value": 97.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-10", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 96.5, + "median": 96.5, + "p10": 96.5, + "p25": 96.5, + "p75": 96.5, + "p90": 96.5, + "n": 1 + }, + { + "month": "2023-08", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2024-04", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-07", + "mean": 100.8, + "median": 100.8, + "p10": 100.8, + "p25": 100.8, + "p75": 100.8, + "p90": 100.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2025-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 98.8, + "median": 98.8, + "p10": 98.5, + "p25": 98.6, + "p75": 99.0, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 98.7, + "median": 98.7, + "p10": 98.4, + "p25": 98.5, + "p75": 98.9, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.0, + "median": 99.2, + "p10": 98.4, + "p25": 98.8, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 98.6, + "median": 98.6, + "p10": 98.0, + "p25": 98.1, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.1, + "median": 98.0, + "p10": 97.7, + "p25": 97.8, + "p75": 98.3, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 98.5, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.7, + "p90": 98.8, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.4, + "median": 98.4, + "p10": 98.2, + "p25": 98.3, + "p75": 98.6, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 98.7, + "median": 98.9, + "p10": 98.1, + "p25": 98.5, + "p75": 99.1, + "p90": 99.2, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 98.7, + "median": 98.8, + "std": 0.7, + "min": 96.5, + "max": 100.8, + "p25": 98.2, + "p75": 99.1, + "p85": 99.3, + "p95": 99.6 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_harbor_dark_roast.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_harbor_dark_roast.json new file mode 100644 index 00000000000..36bd024c6e0 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_duration_harbor_dark_roast.json @@ -0,0 +1,1148 @@ +{ + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "durations": [ + 2.7, 4.1, 1.4, 5.4, 2.7, 6.8, 4.1, 9.5, 2.7, 5.4, 1.4, 4.1, 13.5, 4.1, 2.7, + 6.8, 0.0, 5.4, 4.1, 2.7, 8.1, 4.1, 5.4, 5.4, 4.1, 4.1, 5.4, 2.7, 4.1, 4.1, + 2.7, 2.7, 4.1, 4.1, 4.1, 4.1, 4.1, 5.4, 4.1, 4.1, 4.1, 5.4, 5.4, 5.4, 5.4, + 4.1, 4.1, 5.4, 2.7, 4.1, 4.1, 2.7, 2.7, 4.1, 4.1, 4.1, 4.1, 4.1 + ], + "observations": [ + { + "date": "2022-05-20", + "value": 2.7 + }, + { + "date": "2022-06-10", + "value": 4.1 + }, + { + "date": "2022-07-15", + "value": 1.4 + }, + { + "date": "2022-08-22", + "value": 5.4 + }, + { + "date": "2022-10-05", + "value": 2.7 + }, + { + "date": "2022-11-18", + "value": 6.8 + }, + { + "date": "2023-01-10", + "value": 4.1 + }, + { + "date": "2023-03-25", + "value": 9.5 + }, + { + "date": "2023-05-12", + "value": 2.7 + }, + { + "date": "2023-07-08", + "value": 5.4 + }, + { + "date": "2023-09-15", + "value": 1.4 + }, + { + "date": "2023-11-22", + "value": 4.1 + }, + { + "date": "2024-01-18", + "value": 13.5 + }, + { + "date": "2024-03-08", + "value": 4.1 + }, + { + "date": "2024-05-15", + "value": 2.7 + }, + { + "date": "2024-07-22", + "value": 6.8 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 5.4 + }, + { + "date": "2025-01-15", + "value": 4.1 + }, + { + "date": "2025-03-20", + "value": 2.7 + }, + { + "date": "2025-05-28", + "value": 8.1 + }, + { + "date": "2025-08-05", + "value": 4.1 + }, + { + "date": "2025-09-05", + "value": 5.4 + }, + { + "date": "2025-09-11", + "value": 5.4 + }, + { + "date": "2025-09-17", + "value": 4.1 + }, + { + "date": "2025-09-23", + "value": 4.1 + }, + { + "date": "2025-10-06", + "value": 5.4 + }, + { + "date": "2025-10-12", + "value": 2.7 + }, + { + "date": "2025-10-18", + "value": 4.1 + }, + { + "date": "2025-10-24", + "value": 4.1 + }, + { + "date": "2025-11-04", + "value": 2.7 + }, + { + "date": "2025-11-10", + "value": 2.7 + }, + { + "date": "2025-11-16", + "value": 4.1 + }, + { + "date": "2025-11-22", + "value": 4.1 + }, + { + "date": "2025-12-05", + "value": 4.1 + }, + { + "date": "2025-12-11", + "value": 4.1 + }, + { + "date": "2025-12-17", + "value": 4.1 + }, + { + "date": "2025-12-23", + "value": 5.4 + }, + { + "date": "2026-01-06", + "value": 4.1 + }, + { + "date": "2026-01-12", + "value": 4.1 + }, + { + "date": "2026-01-18", + "value": 4.1 + }, + { + "date": "2026-01-24", + "value": 5.4 + }, + { + "date": "2026-02-04", + "value": 5.4 + }, + { + "date": "2026-02-10", + "value": 5.4 + }, + { + "date": "2026-02-16", + "value": 5.4 + }, + { + "date": "2026-02-22", + "value": 4.1 + }, + { + "date": "2026-03-05", + "value": 4.1 + }, + { + "date": "2026-03-11", + "value": 5.4 + }, + { + "date": "2026-03-17", + "value": 2.7 + }, + { + "date": "2026-03-23", + "value": 4.1 + }, + { + "date": "2026-04-06", + "value": 4.1 + }, + { + "date": "2026-04-12", + "value": 2.7 + }, + { + "date": "2026-04-18", + "value": 2.7 + }, + { + "date": "2026-04-24", + "value": 4.1 + }, + { + "date": "2026-05-04", + "value": 4.1 + }, + { + "date": "2026-05-10", + "value": 4.1 + }, + { + "date": "2026-05-16", + "value": 4.1 + }, + { + "date": "2026-05-22", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-06", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2022-08", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-11", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-03", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2023-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2025-05", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.4, + "median": 3.4, + "p10": 2.7, + "p25": 2.7, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-12", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.4, + "median": 3.4, + "p10": 2.7, + "p25": 2.7, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 4.4, + "median": 4.1, + "std": 1.4, + "min": 0.0, + "max": 13.5, + "p25": 4.1, + "p75": 5.4, + "p85": 5.4, + "p95": 6.8 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 58, + "n_movements": null, + "yield_data": { + "values": [ + 99.0, 98.5, 99.8, 97.2, 99.5, 98.0, 100.2, 98.8, 99.2, 97.5, 99.0, 98.5, + 100.5, 99.2, 98.0, 97.8, 99.5, 98.2, 99.0, 98.8, 99.5, 97.0, 98.9, 99.1, + 99.4, 99.6, 98.8, 99.0, 99.3, 99.6, 99.5, 99.8, 100.1, 98.7, 99.5, 99.8, + 98.4, 98.7, 99.4, 98.1, 98.4, 98.6, 98.6, 98.9, 99.1, 99.4, 98.6, 98.8, + 99.0, 99.3, 99.3, 99.5, 99.8, 100.1, 99.2, 99.5, 99.8, 98.4 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 99.0 + }, + { + "date": "2022-06-13", + "value": 98.5 + }, + { + "date": "2022-07-16", + "value": 99.8 + }, + { + "date": "2022-08-26", + "value": 97.2 + }, + { + "date": "2022-10-07", + "value": 99.5 + }, + { + "date": "2022-11-23", + "value": 98.0 + }, + { + "date": "2023-01-13", + "value": 100.2 + }, + { + "date": "2023-04-01", + "value": 98.8 + }, + { + "date": "2023-05-14", + "value": 99.2 + }, + { + "date": "2023-07-12", + "value": 97.5 + }, + { + "date": "2023-09-16", + "value": 99.0 + }, + { + "date": "2023-11-25", + "value": 98.5 + }, + { + "date": "2024-01-28", + "value": 100.5 + }, + { + "date": "2024-03-11", + "value": 99.2 + }, + { + "date": "2024-05-17", + "value": 98.0 + }, + { + "date": "2024-07-27", + "value": 97.8 + }, + { + "date": "2024-09-10", + "value": 99.5 + }, + { + "date": "2024-11-09", + "value": 98.2 + }, + { + "date": "2025-01-18", + "value": 99.0 + }, + { + "date": "2025-03-22", + "value": 98.8 + }, + { + "date": "2025-06-03", + "value": 99.5 + }, + { + "date": "2025-08-08", + "value": 97.0 + }, + { + "date": "2025-09-05", + "value": 98.9 + }, + { + "date": "2025-09-11", + "value": 99.1 + }, + { + "date": "2025-09-17", + "value": 99.4 + }, + { + "date": "2025-09-23", + "value": 99.6 + }, + { + "date": "2025-10-06", + "value": 98.8 + }, + { + "date": "2025-10-12", + "value": 99.0 + }, + { + "date": "2025-10-18", + "value": 99.3 + }, + { + "date": "2025-10-24", + "value": 99.6 + }, + { + "date": "2025-11-04", + "value": 99.5 + }, + { + "date": "2025-11-10", + "value": 99.8 + }, + { + "date": "2025-11-16", + "value": 100.1 + }, + { + "date": "2025-11-22", + "value": 98.7 + }, + { + "date": "2025-12-05", + "value": 99.5 + }, + { + "date": "2025-12-11", + "value": 99.8 + }, + { + "date": "2025-12-17", + "value": 98.4 + }, + { + "date": "2025-12-23", + "value": 98.7 + }, + { + "date": "2026-01-06", + "value": 99.4 + }, + { + "date": "2026-01-12", + "value": 98.1 + }, + { + "date": "2026-01-18", + "value": 98.4 + }, + { + "date": "2026-01-24", + "value": 98.6 + }, + { + "date": "2026-02-04", + "value": 98.6 + }, + { + "date": "2026-02-10", + "value": 98.9 + }, + { + "date": "2026-02-16", + "value": 99.1 + }, + { + "date": "2026-02-22", + "value": 99.4 + }, + { + "date": "2026-03-05", + "value": 98.6 + }, + { + "date": "2026-03-11", + "value": 98.8 + }, + { + "date": "2026-03-17", + "value": 99.0 + }, + { + "date": "2026-03-23", + "value": 99.3 + }, + { + "date": "2026-04-06", + "value": 99.3 + }, + { + "date": "2026-04-12", + "value": 99.5 + }, + { + "date": "2026-04-18", + "value": 99.8 + }, + { + "date": "2026-04-24", + "value": 100.1 + }, + { + "date": "2026-05-04", + "value": 99.2 + }, + { + "date": "2026-05-10", + "value": 99.5 + }, + { + "date": "2026-05-16", + "value": 99.8 + }, + { + "date": "2026-05-22", + "value": 98.4 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.8, + "median": 99.8, + "p10": 99.8, + "p25": 99.8, + "p75": 99.8, + "p90": 99.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-11", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2023-07", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 100.5, + "median": 100.5, + "p10": 100.5, + "p25": 100.5, + "p75": 100.5, + "p90": 100.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-11", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 97.0, + "median": 97.0, + "p10": 97.0, + "p25": 97.0, + "p75": 97.0, + "p90": 97.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 99.3, + "median": 99.3, + "p10": 99.0, + "p25": 99.1, + "p75": 99.5, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.5, + "median": 99.7, + "p10": 98.9, + "p25": 99.3, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 99.1, + "median": 99.1, + "p10": 98.5, + "p25": 98.6, + "p75": 99.6, + "p90": 99.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.6, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.8, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-02", + "mean": 99.0, + "median": 99.0, + "p10": 98.7, + "p25": 98.8, + "p75": 99.2, + "p90": 99.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.9, + "median": 98.9, + "p10": 98.7, + "p25": 98.8, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.7, + "median": 99.7, + "p10": 99.4, + "p25": 99.5, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 99.2, + "median": 99.4, + "p10": 98.6, + "p25": 99.0, + "p75": 99.6, + "p90": 99.7, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 99.0, + "median": 99.1, + "std": 0.7, + "min": 97.0, + "max": 100.5, + "p25": 98.6, + "p75": 99.5, + "p85": 99.7, + "p95": 100.1 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_to_qa_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_to_qa_pla.json new file mode 100644 index 00000000000..5691dea59b3 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/prod_to_qa_pla.json @@ -0,0 +1,581 @@ +{ + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "durations": [ + 2.7, 1.4, 4.1, 2.7, 6.8, 2.7, 5.4, 4.1, 8.1, 2.7, 17.6, 4.1, 9.5, 1.4, 5.4, + 6.8, 2.7, 0.0, 4.1, 10.8, 2.7, 6.8, 2.7, 4.1, 4.1, 4.1, 4.1, 4.1, 5.4, 5.4, + 4.1, 4.1, 4.1, 5.4, 4.1, 4.1, 4.1, 2.7, 5.4, 5.4, 4.1, 4.1, 5.4, 2.7, 4.1, + 4.1, 4.1, 4.1, 4.1, 5.4, 4.1, 4.1, 4.1, 4.1, 4.1, 4.1, 4.1, 4.1 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 2.7 + }, + { + "date": "2022-06-13", + "value": 1.4 + }, + { + "date": "2022-07-16", + "value": 4.1 + }, + { + "date": "2022-08-26", + "value": 2.7 + }, + { + "date": "2022-10-07", + "value": 6.8 + }, + { + "date": "2022-11-23", + "value": 2.7 + }, + { + "date": "2023-01-13", + "value": 5.4 + }, + { + "date": "2023-04-01", + "value": 4.1 + }, + { + "date": "2023-05-14", + "value": 8.1 + }, + { + "date": "2023-07-12", + "value": 2.7 + }, + { + "date": "2023-09-16", + "value": 17.6 + }, + { + "date": "2023-11-25", + "value": 4.1 + }, + { + "date": "2024-01-28", + "value": 9.5 + }, + { + "date": "2024-03-11", + "value": 1.4 + }, + { + "date": "2024-05-17", + "value": 5.4 + }, + { + "date": "2024-07-27", + "value": 6.8 + }, + { + "date": "2024-09-10", + "value": 2.7 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 4.1 + }, + { + "date": "2025-03-22", + "value": 10.8 + }, + { + "date": "2025-06-03", + "value": 2.7 + }, + { + "date": "2025-08-08", + "value": 6.8 + }, + { + "date": "2025-09-04", + "value": 2.7 + }, + { + "date": "2025-09-10", + "value": 4.1 + }, + { + "date": "2025-09-16", + "value": 4.1 + }, + { + "date": "2025-09-22", + "value": 4.1 + }, + { + "date": "2025-10-05", + "value": 4.1 + }, + { + "date": "2025-10-11", + "value": 4.1 + }, + { + "date": "2025-10-17", + "value": 5.4 + }, + { + "date": "2025-10-23", + "value": 5.4 + }, + { + "date": "2025-11-06", + "value": 4.1 + }, + { + "date": "2025-11-12", + "value": 4.1 + }, + { + "date": "2025-11-18", + "value": 4.1 + }, + { + "date": "2025-11-24", + "value": 5.4 + }, + { + "date": "2025-12-04", + "value": 4.1 + }, + { + "date": "2025-12-10", + "value": 4.1 + }, + { + "date": "2025-12-16", + "value": 4.1 + }, + { + "date": "2025-12-22", + "value": 2.7 + }, + { + "date": "2026-01-05", + "value": 5.4 + }, + { + "date": "2026-01-11", + "value": 5.4 + }, + { + "date": "2026-01-17", + "value": 4.1 + }, + { + "date": "2026-01-23", + "value": 4.1 + }, + { + "date": "2026-02-06", + "value": 5.4 + }, + { + "date": "2026-02-12", + "value": 2.7 + }, + { + "date": "2026-02-18", + "value": 4.1 + }, + { + "date": "2026-02-24", + "value": 4.1 + }, + { + "date": "2026-03-04", + "value": 4.1 + }, + { + "date": "2026-03-10", + "value": 4.1 + }, + { + "date": "2026-03-16", + "value": 4.1 + }, + { + "date": "2026-03-22", + "value": 5.4 + }, + { + "date": "2026-04-05", + "value": 4.1 + }, + { + "date": "2026-04-11", + "value": 4.1 + }, + { + "date": "2026-04-17", + "value": 4.1 + }, + { + "date": "2026-04-23", + "value": 4.1 + }, + { + "date": "2026-05-06", + "value": 4.1 + }, + { + "date": "2026-05-12", + "value": 4.1 + }, + { + "date": "2026-05-18", + "value": 4.1 + }, + { + "date": "2026-05-24", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-01", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-05", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 17.6, + "median": 17.6, + "p10": 17.6, + "p25": 17.6, + "p75": 17.6, + "p90": 17.6, + "n": 1 + }, + { + "month": "2023-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2024-05", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-03", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2025-08", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.8, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.8, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 4.6, + "median": 4.1, + "std": 1.8, + "min": 0.0, + "max": 17.6, + "p25": 4.1, + "p75": 5.4, + "p85": 5.4, + "p95": 8.1 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": null, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_highland_arabica.json new file mode 100644 index 00000000000..85ebb24301c --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_highland_arabica.json @@ -0,0 +1,689 @@ +{ + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "durations": [ + 47.2, 83.7, 24.3, 118.8, 56.7, 74.2, 40.5, 97.2, 33.8, 64.8, 20.2, 128.2, + 175.5, 60.8, 51.3, 87.8, 29.7, 105.3, 6.8, 74.2, 54.0, 37.8, 114.8, 67.5, + 148.5, 43.2, 91.8, 60.8, 124.2, 27.0, 78.3, 47.2, 56.7, 101.2, 16.2, 64.8, + 81.0, 51.3, 66.2, 72.9, 45.9, 52.7, 56.7, 82.4, 55.4, 62.1, 66.2, 71.6, + 48.6, 55.4, 59.4, 64.8, 70.2, 48.6, 52.7, 58.1, 63.5, 68.9, 63.5, 67.5, + 72.9, 78.3, 52.7, 60.8, 66.2, 72.9, 45.9, 52.7, 75.6, 82.4, 55.4, 62.1, + 66.2, 75.6, 48.6, 55.4, 59.4, 64.8, 43.2, 48.6, 52.7, 58.1, 63.5 + ], + "observations": [ + { + "date": "2022-04-02", + "value": 47.2 + }, + { + "date": "2022-04-15", + "value": 83.7 + }, + { + "date": "2022-04-28", + "value": 24.3 + }, + { + "date": "2022-08-05", + "value": 118.8 + }, + { + "date": "2022-08-12", + "value": 56.7 + }, + { + "date": "2022-08-20", + "value": 74.2 + }, + { + "date": "2022-08-28", + "value": 40.5 + }, + { + "date": "2023-01-10", + "value": 97.2 + }, + { + "date": "2023-01-22", + "value": 33.8 + }, + { + "date": "2023-01-30", + "value": 64.8 + }, + { + "date": "2023-06-05", + "value": 20.2 + }, + { + "date": "2023-06-18", + "value": 128.2 + }, + { + "date": "2023-10-03", + "value": 175.5 + }, + { + "date": "2023-10-10", + "value": 60.8 + }, + { + "date": "2023-10-18", + "value": 51.3 + }, + { + "date": "2023-10-25", + "value": 87.8 + }, + { + "date": "2023-10-30", + "value": 29.7 + }, + { + "date": "2024-03-05", + "value": 105.3 + }, + { + "date": "2024-03-12", + "value": 6.8 + }, + { + "date": "2024-03-20", + "value": 74.2 + }, + { + "date": "2024-03-28", + "value": 54.0 + }, + { + "date": "2024-07-08", + "value": 37.8 + }, + { + "date": "2024-07-15", + "value": 114.8 + }, + { + "date": "2024-07-22", + "value": 67.5 + }, + { + "date": "2024-11-04", + "value": 148.5 + }, + { + "date": "2024-11-11", + "value": 43.2 + }, + { + "date": "2024-11-18", + "value": 91.8 + }, + { + "date": "2024-11-25", + "value": 60.8 + }, + { + "date": "2024-11-30", + "value": 124.2 + }, + { + "date": "2025-03-03", + "value": 27.0 + }, + { + "date": "2025-03-10", + "value": 78.3 + }, + { + "date": "2025-03-17", + "value": 47.2 + }, + { + "date": "2025-03-24", + "value": 56.7 + }, + { + "date": "2025-07-02", + "value": 101.2 + }, + { + "date": "2025-07-09", + "value": 16.2 + }, + { + "date": "2025-07-16", + "value": 64.8 + }, + { + "date": "2025-07-23", + "value": 81.0 + }, + { + "date": "2025-07-30", + "value": 51.3 + }, + { + "date": "2025-09-05", + "value": 66.2 + }, + { + "date": "2025-09-11", + "value": 72.9 + }, + { + "date": "2025-09-17", + "value": 45.9 + }, + { + "date": "2025-09-23", + "value": 52.7 + }, + { + "date": "2025-09-29", + "value": 56.7 + }, + { + "date": "2025-10-06", + "value": 82.4 + }, + { + "date": "2025-10-12", + "value": 55.4 + }, + { + "date": "2025-10-18", + "value": 62.1 + }, + { + "date": "2025-10-24", + "value": 66.2 + }, + { + "date": "2025-10-30", + "value": 71.6 + }, + { + "date": "2025-11-04", + "value": 48.6 + }, + { + "date": "2025-11-10", + "value": 55.4 + }, + { + "date": "2025-11-16", + "value": 59.4 + }, + { + "date": "2025-11-22", + "value": 64.8 + }, + { + "date": "2025-11-28", + "value": 70.2 + }, + { + "date": "2025-12-05", + "value": 48.6 + }, + { + "date": "2025-12-11", + "value": 52.7 + }, + { + "date": "2025-12-17", + "value": 58.1 + }, + { + "date": "2025-12-23", + "value": 63.5 + }, + { + "date": "2025-12-29", + "value": 68.9 + }, + { + "date": "2026-01-06", + "value": 63.5 + }, + { + "date": "2026-01-12", + "value": 67.5 + }, + { + "date": "2026-01-18", + "value": 72.9 + }, + { + "date": "2026-01-24", + "value": 78.3 + }, + { + "date": "2026-01-30", + "value": 52.7 + }, + { + "date": "2026-02-04", + "value": 60.8 + }, + { + "date": "2026-02-10", + "value": 66.2 + }, + { + "date": "2026-02-16", + "value": 72.9 + }, + { + "date": "2026-02-22", + "value": 45.9 + }, + { + "date": "2026-02-28", + "value": 52.7 + }, + { + "date": "2026-03-05", + "value": 75.6 + }, + { + "date": "2026-03-11", + "value": 82.4 + }, + { + "date": "2026-03-17", + "value": 55.4 + }, + { + "date": "2026-03-23", + "value": 62.1 + }, + { + "date": "2026-03-29", + "value": 66.2 + }, + { + "date": "2026-04-06", + "value": 75.6 + }, + { + "date": "2026-04-12", + "value": 48.6 + }, + { + "date": "2026-04-18", + "value": 55.4 + }, + { + "date": "2026-04-24", + "value": 59.4 + }, + { + "date": "2026-04-30", + "value": 64.8 + }, + { + "date": "2026-05-04", + "value": 43.2 + }, + { + "date": "2026-05-10", + "value": 48.6 + }, + { + "date": "2026-05-16", + "value": 52.7 + }, + { + "date": "2026-05-22", + "value": 58.1 + }, + { + "date": "2026-05-28", + "value": 63.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 51.7, + "median": 47.2, + "p10": 28.9, + "p25": 35.8, + "p75": 65.5, + "p90": 76.4, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 72.6, + "median": 65.5, + "p10": 45.4, + "p25": 52.7, + "p75": 85.5, + "p90": 105.4, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 65.2, + "median": 64.8, + "p10": 40.0, + "p25": 49.3, + "p75": 81.0, + "p90": 90.7, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 74.2, + "median": 74.2, + "p10": 31.1, + "p25": 47.2, + "p75": 101.2, + "p90": 117.5, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 81.0, + "median": 60.8, + "p10": 38.3, + "p25": 51.3, + "p75": 87.8, + "p90": 140.4, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 60.1, + "median": 64.1, + "p10": 20.9, + "p25": 42.3, + "p75": 82.1, + "p90": 96.0, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 73.3, + "median": 67.5, + "p10": 43.7, + "p25": 52.7, + "p75": 91.1, + "p90": 105.3, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 93.7, + "median": 91.8, + "p10": 50.2, + "p25": 60.8, + "p75": 124.2, + "p90": 138.8, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 52.4, + "median": 52.0, + "p10": 33.1, + "p25": 42.3, + "p75": 62.1, + "p90": 71.8, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 62.9, + "median": 64.8, + "p10": 30.2, + "p25": 51.3, + "p75": 81.0, + "p90": 93.2, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 58.9, + "median": 56.7, + "p10": 48.6, + "p25": 52.7, + "p75": 66.2, + "p90": 70.2, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 67.5, + "median": 66.2, + "p10": 58.1, + "p25": 62.1, + "p75": 71.6, + "p90": 78.0, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 59.7, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 58.3, + "median": 58.1, + "p10": 50.2, + "p25": 52.7, + "p75": 63.5, + "p90": 66.7, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 67.0, + "median": 67.5, + "p10": 57.0, + "p25": 63.5, + "p75": 72.9, + "p90": 76.1, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 59.7, + "median": 60.8, + "p10": 48.6, + "p25": 52.7, + "p75": 66.2, + "p90": 70.2, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 68.3, + "median": 66.2, + "p10": 58.1, + "p25": 62.1, + "p75": 75.6, + "p90": 79.7, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 60.8, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 64.8, + "p90": 71.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 53.2, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 58.1, + "p90": 61.3, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "stats": { + "n": 83, + "mean": 65.2, + "median": 62.1, + "std": 19.8, + "min": 6.8, + "max": 175.5, + "p25": 51.3, + "p75": 72.9, + "p85": 82.4, + "p95": 114.8 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": { + "unit_price": 4.32, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 38, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_lowland_robusta.json new file mode 100644 index 00000000000..0d7c87d270c --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_lowland_robusta.json @@ -0,0 +1,563 @@ +{ + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "durations": [ + 37.8, 60.8, 16.2, 83.7, 44.6, 105.3, 27.0, 74.2, 10.8, 56.7, 87.8, 51.3, + 20.2, 97.2, 33.8, 64.8, 4.1, 114.8, 40.5, 74.2, 29.7, 54.0, 132.3, 24.3, + 52.7, 55.4, 60.8, 40.5, 45.9, 51.3, 55.4, 36.5, 40.5, 43.2, 51.3, 31.1, + 36.5, 39.2, 43.2, 37.8, 43.2, 45.9, 50.0, 54.0, 37.8, 41.9, 44.6, 48.6, + 52.7, 48.6, 52.7, 55.4, 60.8, 40.5, 47.2, 51.3, 55.4, 36.5, 40.5, 45.9, + 51.3, 31.1, 36.5, 39.2, 58.1, 37.8, 43.2, 45.9, 50.0 + ], + "observations": [ + { + "date": "2022-05-02", + "value": 37.8 + }, + { + "date": "2022-05-10", + "value": 60.8 + }, + { + "date": "2022-05-18", + "value": 16.2 + }, + { + "date": "2022-05-25", + "value": 83.7 + }, + { + "date": "2023-02-06", + "value": 44.6 + }, + { + "date": "2023-02-14", + "value": 105.3 + }, + { + "date": "2023-02-22", + "value": 27.0 + }, + { + "date": "2023-02-28", + "value": 74.2 + }, + { + "date": "2023-09-05", + "value": 10.8 + }, + { + "date": "2023-09-15", + "value": 56.7 + }, + { + "date": "2023-09-25", + "value": 87.8 + }, + { + "date": "2024-04-03", + "value": 51.3 + }, + { + "date": "2024-04-10", + "value": 20.2 + }, + { + "date": "2024-04-17", + "value": 97.2 + }, + { + "date": "2024-04-24", + "value": 33.8 + }, + { + "date": "2024-10-02", + "value": 64.8 + }, + { + "date": "2024-10-09", + "value": 4.1 + }, + { + "date": "2024-10-16", + "value": 114.8 + }, + { + "date": "2024-10-23", + "value": 40.5 + }, + { + "date": "2024-10-30", + "value": 74.2 + }, + { + "date": "2025-04-07", + "value": 29.7 + }, + { + "date": "2025-04-14", + "value": 54.0 + }, + { + "date": "2025-04-21", + "value": 132.3 + }, + { + "date": "2025-04-28", + "value": 24.3 + }, + { + "date": "2025-09-04", + "value": 52.7 + }, + { + "date": "2025-09-10", + "value": 55.4 + }, + { + "date": "2025-09-16", + "value": 60.8 + }, + { + "date": "2025-09-22", + "value": 40.5 + }, + { + "date": "2025-09-28", + "value": 45.9 + }, + { + "date": "2025-10-05", + "value": 51.3 + }, + { + "date": "2025-10-11", + "value": 55.4 + }, + { + "date": "2025-10-17", + "value": 36.5 + }, + { + "date": "2025-10-23", + "value": 40.5 + }, + { + "date": "2025-10-29", + "value": 43.2 + }, + { + "date": "2025-11-06", + "value": 51.3 + }, + { + "date": "2025-11-12", + "value": 31.1 + }, + { + "date": "2025-11-18", + "value": 36.5 + }, + { + "date": "2025-11-24", + "value": 39.2 + }, + { + "date": "2025-11-30", + "value": 43.2 + }, + { + "date": "2025-12-04", + "value": 37.8 + }, + { + "date": "2025-12-10", + "value": 43.2 + }, + { + "date": "2025-12-16", + "value": 45.9 + }, + { + "date": "2025-12-22", + "value": 50.0 + }, + { + "date": "2025-12-28", + "value": 54.0 + }, + { + "date": "2026-01-05", + "value": 37.8 + }, + { + "date": "2026-01-11", + "value": 41.9 + }, + { + "date": "2026-01-17", + "value": 44.6 + }, + { + "date": "2026-01-23", + "value": 48.6 + }, + { + "date": "2026-01-29", + "value": 52.7 + }, + { + "date": "2026-02-06", + "value": 48.6 + }, + { + "date": "2026-02-12", + "value": 52.7 + }, + { + "date": "2026-02-18", + "value": 55.4 + }, + { + "date": "2026-02-24", + "value": 60.8 + }, + { + "date": "2026-02-30", + "value": 40.5 + }, + { + "date": "2026-03-04", + "value": 47.2 + }, + { + "date": "2026-03-10", + "value": 51.3 + }, + { + "date": "2026-03-16", + "value": 55.4 + }, + { + "date": "2026-03-22", + "value": 36.5 + }, + { + "date": "2026-03-28", + "value": 40.5 + }, + { + "date": "2026-04-05", + "value": 45.9 + }, + { + "date": "2026-04-11", + "value": 51.3 + }, + { + "date": "2026-04-17", + "value": 31.1 + }, + { + "date": "2026-04-23", + "value": 36.5 + }, + { + "date": "2026-04-29", + "value": 39.2 + }, + { + "date": "2026-05-06", + "value": 58.1 + }, + { + "date": "2026-05-12", + "value": 37.8 + }, + { + "date": "2026-05-18", + "value": 43.2 + }, + { + "date": "2026-05-24", + "value": 45.9 + }, + { + "date": "2026-05-30", + "value": 50.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 49.7, + "median": 49.3, + "p10": 22.7, + "p25": 32.4, + "p75": 66.6, + "p90": 76.8, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 62.8, + "median": 59.4, + "p10": 32.3, + "p25": 40.2, + "p75": 82.1, + "p90": 96.0, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 51.7, + "median": 56.7, + "p10": 20.0, + "p25": 33.8, + "p75": 72.2, + "p90": 81.5, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 50.6, + "median": 42.5, + "p10": 24.3, + "p25": 30.4, + "p75": 62.8, + "p90": 83.4, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 59.7, + "median": 64.8, + "p10": 18.6, + "p25": 40.5, + "p75": 74.2, + "p90": 98.6, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 60.1, + "median": 41.9, + "p10": 25.9, + "p25": 28.4, + "p75": 73.6, + "p90": 108.8, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 51.0, + "median": 52.7, + "p10": 42.7, + "p25": 45.9, + "p75": 55.4, + "p90": 58.6, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 45.4, + "median": 43.2, + "p10": 38.1, + "p25": 40.5, + "p75": 51.3, + "p90": 53.7, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 40.2, + "median": 39.2, + "p10": 33.2, + "p25": 36.5, + "p75": 43.2, + "p90": 48.1, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 46.2, + "median": 45.9, + "p10": 40.0, + "p25": 43.2, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 45.1, + "median": 44.6, + "p10": 39.4, + "p25": 41.9, + "p75": 48.6, + "p90": 51.0, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 51.6, + "median": 52.7, + "p10": 43.7, + "p25": 48.6, + "p75": 55.4, + "p90": 58.6, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 46.2, + "median": 47.2, + "p10": 38.1, + "p25": 40.5, + "p75": 51.3, + "p90": 53.7, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 40.8, + "median": 39.2, + "p10": 33.2, + "p25": 36.5, + "p75": 45.9, + "p90": 49.1, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 47.0, + "median": 45.9, + "p10": 40.0, + "p25": 43.2, + "p75": 50.0, + "p90": 54.8, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "stats": { + "n": 69, + "mean": 49.5, + "median": 45.9, + "std": 15.8, + "min": 4.1, + "max": 132.3, + "p25": 37.8, + "p75": 55.4, + "p85": 60.8, + "p95": 87.8 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "annotations": [], + "cost": { + "unit_price": 2.43, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 42, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_washed_bourbon.json new file mode 100644 index 00000000000..9f66b99b8a5 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/raw_dwell_washed_bourbon.json @@ -0,0 +1,567 @@ +{ + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "durations": [ + 54.0, 29.7, 91.8, 5.4, 74.2, 155.2, 40.5, 83.7, 24.3, 114.8, 47.2, 97.2, + 13.5, 64.8, 128.2, 37.8, 70.2, 20.2, 105.3, 56.7, 10.8, 87.8, 44.6, 135.0, + 27.0, 55.4, 60.8, 64.8, 70.2, 45.9, 54.0, 59.4, 64.8, 40.5, 45.9, 67.5, + 72.9, 48.6, 55.4, 59.4, 67.5, 43.2, 48.6, 52.7, 58.1, 37.8, 43.2, 47.2, + 51.3, 56.7, 52.7, 55.4, 60.8, 64.8, 70.2, 50.0, 54.0, 59.4, 64.8, 40.5, + 63.5, 67.5, 72.9, 48.6, 55.4, 62.1, 67.5, 43.2, 48.6, 52.7 + ], + "observations": [ + { + "date": "2022-06-05", + "value": 54.0 + }, + { + "date": "2022-06-15", + "value": 29.7 + }, + { + "date": "2022-06-25", + "value": 91.8 + }, + { + "date": "2023-03-08", + "value": 5.4 + }, + { + "date": "2023-03-15", + "value": 74.2 + }, + { + "date": "2023-03-22", + "value": 155.2 + }, + { + "date": "2023-03-29", + "value": 40.5 + }, + { + "date": "2023-11-06", + "value": 83.7 + }, + { + "date": "2023-11-13", + "value": 24.3 + }, + { + "date": "2023-11-20", + "value": 114.8 + }, + { + "date": "2024-06-03", + "value": 47.2 + }, + { + "date": "2024-06-10", + "value": 97.2 + }, + { + "date": "2024-06-17", + "value": 13.5 + }, + { + "date": "2024-06-24", + "value": 64.8 + }, + { + "date": "2024-06-30", + "value": 128.2 + }, + { + "date": "2025-01-07", + "value": 37.8 + }, + { + "date": "2025-01-14", + "value": 70.2 + }, + { + "date": "2025-01-21", + "value": 20.2 + }, + { + "date": "2025-01-28", + "value": 105.3 + }, + { + "date": "2025-08-04", + "value": 56.7 + }, + { + "date": "2025-08-08", + "value": 10.8 + }, + { + "date": "2025-08-12", + "value": 87.8 + }, + { + "date": "2025-08-16", + "value": 44.6 + }, + { + "date": "2025-08-20", + "value": 135.0 + }, + { + "date": "2025-08-24", + "value": 27.0 + }, + { + "date": "2025-09-06", + "value": 55.4 + }, + { + "date": "2025-09-12", + "value": 60.8 + }, + { + "date": "2025-09-18", + "value": 64.8 + }, + { + "date": "2025-09-24", + "value": 70.2 + }, + { + "date": "2025-09-30", + "value": 45.9 + }, + { + "date": "2025-10-04", + "value": 54.0 + }, + { + "date": "2025-10-10", + "value": 59.4 + }, + { + "date": "2025-10-16", + "value": 64.8 + }, + { + "date": "2025-10-22", + "value": 40.5 + }, + { + "date": "2025-10-28", + "value": 45.9 + }, + { + "date": "2025-11-05", + "value": 67.5 + }, + { + "date": "2025-11-11", + "value": 72.9 + }, + { + "date": "2025-11-17", + "value": 48.6 + }, + { + "date": "2025-11-23", + "value": 55.4 + }, + { + "date": "2025-11-29", + "value": 59.4 + }, + { + "date": "2025-12-06", + "value": 67.5 + }, + { + "date": "2025-12-12", + "value": 43.2 + }, + { + "date": "2025-12-18", + "value": 48.6 + }, + { + "date": "2025-12-24", + "value": 52.7 + }, + { + "date": "2025-12-30", + "value": 58.1 + }, + { + "date": "2026-01-04", + "value": 37.8 + }, + { + "date": "2026-01-10", + "value": 43.2 + }, + { + "date": "2026-01-16", + "value": 47.2 + }, + { + "date": "2026-01-22", + "value": 51.3 + }, + { + "date": "2026-01-28", + "value": 56.7 + }, + { + "date": "2026-02-05", + "value": 52.7 + }, + { + "date": "2026-02-11", + "value": 55.4 + }, + { + "date": "2026-02-17", + "value": 60.8 + }, + { + "date": "2026-02-23", + "value": 64.8 + }, + { + "date": "2026-02-29", + "value": 70.2 + }, + { + "date": "2026-03-06", + "value": 50.0 + }, + { + "date": "2026-03-12", + "value": 54.0 + }, + { + "date": "2026-03-18", + "value": 59.4 + }, + { + "date": "2026-03-24", + "value": 64.8 + }, + { + "date": "2026-03-30", + "value": 40.5 + }, + { + "date": "2026-04-04", + "value": 63.5 + }, + { + "date": "2026-04-10", + "value": 67.5 + }, + { + "date": "2026-04-16", + "value": 72.9 + }, + { + "date": "2026-04-22", + "value": 48.6 + }, + { + "date": "2026-04-28", + "value": 55.4 + }, + { + "date": "2026-05-05", + "value": 62.1 + }, + { + "date": "2026-05-11", + "value": 67.5 + }, + { + "date": "2026-05-17", + "value": 43.2 + }, + { + "date": "2026-05-23", + "value": 48.6 + }, + { + "date": "2026-05-29", + "value": 52.7 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 58.5, + "median": 54.0, + "p10": 34.6, + "p25": 41.9, + "p75": 72.9, + "p90": 84.2, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 68.9, + "median": 57.4, + "p10": 15.9, + "p25": 31.7, + "p75": 94.5, + "p90": 131.0, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 74.2, + "median": 83.7, + "p10": 36.2, + "p25": 54.0, + "p75": 99.2, + "p90": 108.5, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 70.2, + "median": 64.8, + "p10": 27.0, + "p25": 47.2, + "p75": 97.2, + "p90": 115.8, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 58.5, + "median": 54.0, + "p10": 25.5, + "p25": 33.5, + "p75": 79.0, + "p90": 94.8, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 60.3, + "median": 50.6, + "p10": 18.9, + "p25": 31.5, + "p75": 80.1, + "p90": 111.4, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 59.4, + "median": 60.8, + "p10": 49.7, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 52.9, + "median": 54.0, + "p10": 42.7, + "p25": 45.9, + "p75": 59.4, + "p90": 62.6, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 60.8, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 67.5, + "p90": 70.7, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 54.0, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 58.1, + "p90": 63.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 47.2, + "median": 47.2, + "p10": 40.0, + "p25": 43.2, + "p75": 51.3, + "p90": 54.5, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 60.8, + "median": 60.8, + "p10": 53.7, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 53.7, + "median": 54.0, + "p10": 44.3, + "p25": 50.0, + "p75": 59.4, + "p90": 62.6, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 61.6, + "median": 63.5, + "p10": 51.3, + "p25": 55.4, + "p75": 67.5, + "p90": 70.7, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 54.8, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 62.1, + "p90": 65.3, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "stats": { + "n": 70, + "mean": 59.2, + "median": 55.4, + "std": 19.1, + "min": 5.4, + "max": 155.2, + "p25": 45.9, + "p75": 67.5, + "p85": 72.9, + "p95": 105.3 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "annotations": [], + "cost": { + "unit_price": 7.425, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 25, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/transit_pla_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/transit_pla_hub1.json new file mode 100644 index 00000000000..8b1cc2cbd93 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/meadow-espresso/steps/transit_pla_hub1.json @@ -0,0 +1,437 @@ +{ + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "durations": [ + 37.8, 47.2, 29.7, 56.7, 40.5, 74.2, 33.8, 51.3, 20.2, 43.2, 37.8, 60.8, + 40.5, 29.7, 48.6, 51.3, 52.7, 35.1, 48.6, 31.1, 35.1, 36.5, 41.9, 44.6, + 36.5, 39.2, 43.2, 35.1, 39.2, 41.9, 44.6, 48.6, 52.7, 44.6, 48.6, 31.1, + 54.0, 36.5, 41.9, 32.4, 36.5, 39.2 + ], + "observations": [ + { + "date": "2022-07-20", + "value": 37.8 + }, + { + "date": "2022-11-30", + "value": 47.2 + }, + { + "date": "2023-03-15", + "value": 29.7 + }, + { + "date": "2023-07-10", + "value": 56.7 + }, + { + "date": "2023-10-25", + "value": 40.5 + }, + { + "date": "2024-02-08", + "value": 74.2 + }, + { + "date": "2024-05-20", + "value": 33.8 + }, + { + "date": "2024-08-12", + "value": 51.3 + }, + { + "date": "2024-11-05", + "value": 20.2 + }, + { + "date": "2025-01-22", + "value": 43.2 + }, + { + "date": "2025-04-10", + "value": 37.8 + }, + { + "date": "2025-06-18", + "value": 60.8 + }, + { + "date": "2025-07-15", + "value": 40.5 + }, + { + "date": "2025-08-05", + "value": 29.7 + }, + { + "date": "2025-09-05", + "value": 48.6 + }, + { + "date": "2025-09-10", + "value": 51.3 + }, + { + "date": "2025-09-11", + "value": 52.7 + }, + { + "date": "2025-09-17", + "value": 35.1 + }, + { + "date": "2025-10-06", + "value": 48.6 + }, + { + "date": "2025-10-12", + "value": 31.1 + }, + { + "date": "2025-10-18", + "value": 35.1 + }, + { + "date": "2025-11-04", + "value": 36.5 + }, + { + "date": "2025-11-10", + "value": 41.9 + }, + { + "date": "2025-11-16", + "value": 44.6 + }, + { + "date": "2025-12-05", + "value": 36.5 + }, + { + "date": "2025-12-11", + "value": 39.2 + }, + { + "date": "2025-12-17", + "value": 43.2 + }, + { + "date": "2026-01-06", + "value": 35.1 + }, + { + "date": "2026-01-12", + "value": 39.2 + }, + { + "date": "2026-01-18", + "value": 41.9 + }, + { + "date": "2026-02-04", + "value": 44.6 + }, + { + "date": "2026-02-10", + "value": 48.6 + }, + { + "date": "2026-02-16", + "value": 52.7 + }, + { + "date": "2026-03-05", + "value": 44.6 + }, + { + "date": "2026-03-11", + "value": 48.6 + }, + { + "date": "2026-03-17", + "value": 31.1 + }, + { + "date": "2026-04-06", + "value": 54.0 + }, + { + "date": "2026-04-12", + "value": 36.5 + }, + { + "date": "2026-04-18", + "value": 41.9 + }, + { + "date": "2026-05-04", + "value": 32.4 + }, + { + "date": "2026-05-10", + "value": 36.5 + }, + { + "date": "2026-05-16", + "value": 39.2 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2022-11", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2023-03", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1 + }, + { + "month": "2023-10", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2024-02", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-08", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-11", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 43.2, + "median": 43.2, + "p10": 43.2, + "p25": 43.2, + "p75": 43.2, + "p90": 43.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 60.8, + "median": 60.8, + "p10": 60.8, + "p25": 60.8, + "p75": 60.8, + "p90": 60.8, + "n": 1 + }, + { + "month": "2025-07", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 47.0, + "median": 50.0, + "p10": 39.2, + "p25": 45.2, + "p75": 51.7, + "p90": 52.2, + "n": 4 + }, + { + "month": "2025-10", + "mean": 38.2, + "median": 35.1, + "p10": 31.9, + "p25": 33.1, + "p75": 41.9, + "p90": 45.9, + "n": 3 + }, + { + "month": "2025-11", + "mean": 40.9, + "median": 41.9, + "p10": 37.5, + "p25": 39.2, + "p75": 43.2, + "p90": 44.0, + "n": 3 + }, + { + "month": "2025-12", + "mean": 39.6, + "median": 39.2, + "p10": 37.0, + "p25": 37.8, + "p75": 41.2, + "p90": 42.4, + "n": 3 + }, + { + "month": "2026-01", + "mean": 38.7, + "median": 39.2, + "p10": 35.9, + "p25": 37.1, + "p75": 40.5, + "p90": 41.3, + "n": 3 + }, + { + "month": "2026-02", + "mean": 48.6, + "median": 48.6, + "p10": 45.4, + "p25": 46.6, + "p75": 50.6, + "p90": 51.8, + "n": 3 + }, + { + "month": "2026-03", + "mean": 41.4, + "median": 44.6, + "p10": 33.8, + "p25": 37.8, + "p75": 46.6, + "p90": 47.8, + "n": 3 + }, + { + "month": "2026-04", + "mean": 44.1, + "median": 41.9, + "p10": 37.5, + "p25": 39.2, + "p75": 47.9, + "p90": 51.6, + "n": 3 + }, + { + "month": "2026-05", + "mean": 36.0, + "median": 36.5, + "p10": 33.2, + "p25": 34.4, + "p75": 37.8, + "p90": 38.6, + "n": 3 + } + ], + "stats": { + "n": 42, + "mean": 42.3, + "median": 40.5, + "std": 7.1, + "min": 20.2, + "max": 74.2, + "p25": 36.5, + "p75": 48.6, + "p85": 51.3, + "p95": 54.0 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 15, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/products.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/products.json new file mode 100644 index 00000000000..704a0f39275 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/products.json @@ -0,0 +1,22 @@ +[ + { + "id": "harbor-dark-roast", + "name": "Harbor Dark Roast", + "material": "90000300001" + }, + { + "id": "summit-medium-roast", + "name": "Summit Medium Roast", + "material": "90000300002" + }, + { + "id": "riverside-decaf", + "name": "Riverside Decaf", + "material": "90000300003" + }, + { + "id": "meadow-espresso", + "name": "Meadow Espresso", + "material": "90000300004" + } +] diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/graph.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/graph.json new file mode 100644 index 00000000000..296c2f9c619 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/graph.json @@ -0,0 +1,16588 @@ +{ + "product_id": "riverside-decaf", + "product_name": "Riverside Decaf", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 33.0, + "median": 32.8, + "std": 10.9, + "min": 6.6, + "max": 86.1, + "p25": 28.7, + "p75": 36.9, + "p85": 39.4, + "p95": 45.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 45.1 + }, + { + "date": "2022-06-10", + "value": 34.4 + }, + { + "date": "2022-09-22", + "value": 6.6 + }, + { + "date": "2022-12-05", + "value": 51.7 + }, + { + "date": "2023-02-14", + "value": 31.2 + }, + { + "date": "2023-05-30", + "value": 18.0 + }, + { + "date": "2023-08-17", + "value": 58.2 + }, + { + "date": "2023-11-02", + "value": 24.6 + }, + { + "date": "2024-01-25", + "value": 36.9 + }, + { + "date": "2024-04-11", + "value": 14.8 + }, + { + "date": "2024-07-09", + "value": 86.1 + }, + { + "date": "2024-10-03", + "value": 28.7 + }, + { + "date": "2025-01-20", + "value": 9.8 + }, + { + "date": "2025-04-08", + "value": 39.4 + }, + { + "date": "2025-09-05", + "value": 32.0 + }, + { + "date": "2025-09-11", + "value": 33.6 + }, + { + "date": "2025-09-17", + "value": 36.1 + }, + { + "date": "2025-09-23", + "value": 39.4 + }, + { + "date": "2025-09-29", + "value": 41.8 + }, + { + "date": "2025-10-06", + "value": 30.3 + }, + { + "date": "2025-10-12", + "value": 32.8 + }, + { + "date": "2025-10-18", + "value": 36.1 + }, + { + "date": "2025-10-24", + "value": 38.5 + }, + { + "date": "2025-10-30", + "value": 25.4 + }, + { + "date": "2025-11-04", + "value": 29.5 + }, + { + "date": "2025-11-10", + "value": 32.8 + }, + { + "date": "2025-11-16", + "value": 35.3 + }, + { + "date": "2025-11-22", + "value": 22.1 + }, + { + "date": "2025-11-28", + "value": 25.4 + }, + { + "date": "2025-12-05", + "value": 37.7 + }, + { + "date": "2025-12-11", + "value": 40.2 + }, + { + "date": "2025-12-17", + "value": 27.1 + }, + { + "date": "2025-12-23", + "value": 30.3 + }, + { + "date": "2025-12-29", + "value": 32.0 + }, + { + "date": "2026-01-06", + "value": 36.9 + }, + { + "date": "2026-01-12", + "value": 23.8 + }, + { + "date": "2026-01-18", + "value": 27.1 + }, + { + "date": "2026-01-24", + "value": 28.7 + }, + { + "date": "2026-01-30", + "value": 31.2 + }, + { + "date": "2026-02-04", + "value": 28.7 + }, + { + "date": "2026-02-10", + "value": 32.0 + }, + { + "date": "2026-02-16", + "value": 33.6 + }, + { + "date": "2026-02-22", + "value": 36.1 + }, + { + "date": "2026-02-28", + "value": 39.4 + }, + { + "date": "2026-03-05", + "value": 28.7 + }, + { + "date": "2026-03-11", + "value": 30.3 + }, + { + "date": "2026-03-17", + "value": 32.8 + }, + { + "date": "2026-03-23", + "value": 36.1 + }, + { + "date": "2026-03-29", + "value": 38.5 + }, + { + "date": "2026-04-06", + "value": 27.1 + }, + { + "date": "2026-04-12", + "value": 29.5 + }, + { + "date": "2026-04-18", + "value": 32.8 + }, + { + "date": "2026-04-24", + "value": 35.3 + }, + { + "date": "2026-04-30", + "value": 22.1 + }, + { + "date": "2026-05-04", + "value": 34.4 + }, + { + "date": "2026-05-10", + "value": 37.7 + }, + { + "date": "2026-05-16", + "value": 40.2 + }, + { + "date": "2026-05-22", + "value": 27.1 + }, + { + "date": "2026-05-28", + "value": 30.3 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2022-06", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1 + }, + { + "month": "2022-09", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2022-12", + "mean": 51.7, + "median": 51.7, + "p10": 51.7, + "p25": 51.7, + "p75": 51.7, + "p90": 51.7, + "n": 1 + }, + { + "month": "2023-02", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2023-05", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 58.2, + "median": 58.2, + "p10": 58.2, + "p25": 58.2, + "p75": 58.2, + "p90": 58.2, + "n": 1 + }, + { + "month": "2023-11", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2024-01", + "mean": 36.9, + "median": 36.9, + "p10": 36.9, + "p25": 36.9, + "p75": 36.9, + "p90": 36.9, + "n": 1 + }, + { + "month": "2024-04", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2024-07", + "mean": 86.1, + "median": 86.1, + "p10": 86.1, + "p25": 86.1, + "p75": 86.1, + "p90": 86.1, + "n": 1 + }, + { + "month": "2024-10", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2025-04", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2025-09", + "mean": 36.6, + "median": 36.1, + "p10": 32.6, + "p25": 33.6, + "p75": 39.4, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 32.6, + "median": 32.8, + "p10": 27.4, + "p25": 30.3, + "p75": 36.1, + "p90": 37.6, + "n": 5 + }, + { + "month": "2025-11", + "mean": 29.0, + "median": 29.5, + "p10": 23.5, + "p25": 25.4, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2025-12", + "mean": 33.5, + "median": 32.0, + "p10": 28.4, + "p25": 30.3, + "p75": 37.7, + "p90": 39.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 29.5, + "median": 28.7, + "p10": 25.1, + "p25": 27.1, + "p75": 31.2, + "p90": 34.6, + "n": 5 + }, + { + "month": "2026-02", + "mean": 33.9, + "median": 33.6, + "p10": 30.0, + "p25": 32.0, + "p75": 36.1, + "p90": 38.0, + "n": 5 + }, + { + "month": "2026-03", + "mean": 33.3, + "median": 32.8, + "p10": 29.4, + "p25": 30.3, + "p75": 36.1, + "p90": 37.6, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.4, + "median": 29.5, + "p10": 24.1, + "p25": 27.1, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 33.9, + "median": 34.4, + "p10": 28.4, + "p25": 30.3, + "p75": 37.7, + "p90": 39.2, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 27.4, + "median": 27.1, + "std": 9.3, + "min": 4.1, + "max": 67.2, + "p25": 23.0, + "p75": 31.2, + "p85": 33.4, + "p95": 42.3 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 26.2 + }, + { + "date": "2022-04-19", + "value": 39.4 + }, + { + "date": "2022-07-11", + "value": 4.1 + }, + { + "date": "2022-09-28", + "value": 54.9 + }, + { + "date": "2022-12-15", + "value": 20.5 + }, + { + "date": "2023-03-07", + "value": 33.6 + }, + { + "date": "2023-05-22", + "value": 12.3 + }, + { + "date": "2023-08-09", + "value": 67.2 + }, + { + "date": "2023-10-30", + "value": 31.2 + }, + { + "date": "2024-01-16", + "value": 16.4 + }, + { + "date": "2024-03-25", + "value": 42.6 + }, + { + "date": "2024-06-12", + "value": 8.2 + }, + { + "date": "2024-08-28", + "value": 36.1 + }, + { + "date": "2024-11-14", + "value": 23.0 + }, + { + "date": "2025-01-06", + "value": 28.7 + }, + { + "date": "2025-03-18", + "value": 14.8 + }, + { + "date": "2025-05-29", + "value": 45.1 + }, + { + "date": "2025-08-12", + "value": 21.3 + }, + { + "date": "2025-09-04", + "value": 21.3 + }, + { + "date": "2025-09-10", + "value": 23.8 + }, + { + "date": "2025-09-16", + "value": 25.4 + }, + { + "date": "2025-09-22", + "value": 27.9 + }, + { + "date": "2025-09-28", + "value": 30.3 + }, + { + "date": "2025-10-05", + "value": 21.3 + }, + { + "date": "2025-10-11", + "value": 23.0 + }, + { + "date": "2025-10-17", + "value": 25.4 + }, + { + "date": "2025-10-23", + "value": 27.1 + }, + { + "date": "2025-10-29", + "value": 29.5 + }, + { + "date": "2025-11-06", + "value": 27.1 + }, + { + "date": "2025-11-12", + "value": 29.5 + }, + { + "date": "2025-11-18", + "value": 31.2 + }, + { + "date": "2025-11-24", + "value": 34.4 + }, + { + "date": "2025-11-30", + "value": 23.0 + }, + { + "date": "2025-12-04", + "value": 26.2 + }, + { + "date": "2025-12-10", + "value": 28.7 + }, + { + "date": "2025-12-16", + "value": 31.2 + }, + { + "date": "2025-12-22", + "value": 19.7 + }, + { + "date": "2025-12-28", + "value": 23.0 + }, + { + "date": "2026-01-05", + "value": 32.8 + }, + { + "date": "2026-01-11", + "value": 35.3 + }, + { + "date": "2026-01-17", + "value": 23.8 + }, + { + "date": "2026-01-23", + "value": 27.1 + }, + { + "date": "2026-01-29", + "value": 28.7 + }, + { + "date": "2026-02-06", + "value": 32.8 + }, + { + "date": "2026-02-12", + "value": 21.3 + }, + { + "date": "2026-02-18", + "value": 23.8 + }, + { + "date": "2026-02-24", + "value": 25.4 + }, + { + "date": "2026-02-30", + "value": 27.9 + }, + { + "date": "2026-03-04", + "value": 18.0 + }, + { + "date": "2026-03-10", + "value": 21.3 + }, + { + "date": "2026-03-16", + "value": 23.0 + }, + { + "date": "2026-03-22", + "value": 25.4 + }, + { + "date": "2026-03-28", + "value": 27.1 + }, + { + "date": "2026-04-05", + "value": 25.4 + }, + { + "date": "2026-04-11", + "value": 27.1 + }, + { + "date": "2026-04-17", + "value": 29.5 + }, + { + "date": "2026-04-23", + "value": 31.2 + }, + { + "date": "2026-04-29", + "value": 34.4 + }, + { + "date": "2026-05-06", + "value": 24.6 + }, + { + "date": "2026-05-12", + "value": 26.2 + }, + { + "date": "2026-05-18", + "value": 28.7 + }, + { + "date": "2026-05-24", + "value": 31.2 + }, + { + "date": "2026-05-30", + "value": 19.7 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 26.2, + "median": 26.2, + "p10": 26.2, + "p25": 26.2, + "p75": 26.2, + "p90": 26.2, + "n": 1 + }, + { + "month": "2022-04", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-09", + "mean": 54.9, + "median": 54.9, + "p10": 54.9, + "p25": 54.9, + "p75": 54.9, + "p90": 54.9, + "n": 1 + }, + { + "month": "2022-12", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 33.6, + "median": 33.6, + "p10": 33.6, + "p25": 33.6, + "p75": 33.6, + "p90": 33.6, + "n": 1 + }, + { + "month": "2023-05", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2023-08", + "mean": 67.2, + "median": 67.2, + "p10": 67.2, + "p25": 67.2, + "p75": 67.2, + "p90": 67.2, + "n": 1 + }, + { + "month": "2023-10", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-01", + "mean": 16.4, + "median": 16.4, + "p10": 16.4, + "p25": 16.4, + "p75": 16.4, + "p90": 16.4, + "n": 1 + }, + { + "month": "2024-03", + "mean": 42.6, + "median": 42.6, + "p10": 42.6, + "p25": 42.6, + "p75": 42.6, + "p90": 42.6, + "n": 1 + }, + { + "month": "2024-06", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1 + }, + { + "month": "2024-08", + "mean": 36.1, + "median": 36.1, + "p10": 36.1, + "p25": 36.1, + "p75": 36.1, + "p90": 36.1, + "n": 1 + }, + { + "month": "2024-11", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2025-03", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2025-05", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 21.3, + "median": 21.3, + "p10": 21.3, + "p25": 21.3, + "p75": 21.3, + "p90": 21.3, + "n": 1 + }, + { + "month": "2025-09", + "mean": 25.7, + "median": 25.4, + "p10": 22.3, + "p25": 23.8, + "p75": 27.9, + "p90": 29.4, + "n": 5 + }, + { + "month": "2025-10", + "mean": 25.3, + "median": 25.4, + "p10": 22.0, + "p25": 23.0, + "p75": 27.1, + "p90": 28.5, + "n": 5 + }, + { + "month": "2025-11", + "mean": 29.0, + "median": 29.5, + "p10": 24.6, + "p25": 27.1, + "p75": 31.2, + "p90": 33.1, + "n": 5 + }, + { + "month": "2025-12", + "mean": 25.7, + "median": 26.2, + "p10": 21.0, + "p25": 23.0, + "p75": 28.7, + "p90": 30.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 29.5, + "median": 28.7, + "p10": 25.1, + "p25": 27.1, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2026-02", + "mean": 26.2, + "median": 25.4, + "p10": 22.3, + "p25": 23.8, + "p75": 27.9, + "p90": 30.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 23.0, + "median": 23.0, + "p10": 19.4, + "p25": 21.3, + "p75": 25.4, + "p90": 26.4, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.5, + "median": 29.5, + "p10": 26.1, + "p25": 27.1, + "p75": 31.2, + "p90": 33.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 26.1, + "median": 26.2, + "p10": 21.6, + "p25": 24.6, + "p75": 28.7, + "p90": 30.2, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 21.4, + "median": 20.5, + "std": 6.6, + "min": 5.7, + "max": 50.8, + "p25": 18.4, + "p75": 23.8, + "p85": 24.6, + "p95": 29.9 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 28.7 + }, + { + "date": "2022-10-18", + "value": 13.1 + }, + { + "date": "2023-01-24", + "value": 50.8 + }, + { + "date": "2023-06-15", + "value": 5.7 + }, + { + "date": "2023-09-28", + "value": 32.8 + }, + { + "date": "2024-02-12", + "value": 20.5 + }, + { + "date": "2024-05-07", + "value": 39.4 + }, + { + "date": "2024-09-19", + "value": 9.8 + }, + { + "date": "2025-02-04", + "value": 24.6 + }, + { + "date": "2025-06-10", + "value": 11.5 + }, + { + "date": "2025-09-06", + "value": 24.6 + }, + { + "date": "2025-09-12", + "value": 15.6 + }, + { + "date": "2025-09-18", + "value": 18.0 + }, + { + "date": "2025-09-24", + "value": 18.9 + }, + { + "date": "2025-09-30", + "value": 20.5 + }, + { + "date": "2025-10-04", + "value": 18.9 + }, + { + "date": "2025-10-10", + "value": 20.5 + }, + { + "date": "2025-10-16", + "value": 22.1 + }, + { + "date": "2025-10-22", + "value": 23.8 + }, + { + "date": "2025-10-28", + "value": 25.4 + }, + { + "date": "2025-11-05", + "value": 18.9 + }, + { + "date": "2025-11-11", + "value": 20.5 + }, + { + "date": "2025-11-17", + "value": 22.1 + }, + { + "date": "2025-11-23", + "value": 23.8 + }, + { + "date": "2025-11-29", + "value": 25.4 + }, + { + "date": "2025-12-06", + "value": 18.0 + }, + { + "date": "2025-12-12", + "value": 19.7 + }, + { + "date": "2025-12-18", + "value": 21.3 + }, + { + "date": "2025-12-24", + "value": 23.0 + }, + { + "date": "2025-12-30", + "value": 14.8 + }, + { + "date": "2026-01-04", + "value": 23.0 + }, + { + "date": "2026-01-10", + "value": 24.6 + }, + { + "date": "2026-01-16", + "value": 26.2 + }, + { + "date": "2026-01-22", + "value": 18.0 + }, + { + "date": "2026-01-28", + "value": 19.7 + }, + { + "date": "2026-02-05", + "value": 22.1 + }, + { + "date": "2026-02-11", + "value": 24.6 + }, + { + "date": "2026-02-17", + "value": 15.6 + }, + { + "date": "2026-02-23", + "value": 18.0 + }, + { + "date": "2026-02-29", + "value": 18.9 + }, + { + "date": "2026-03-06", + "value": 27.9 + }, + { + "date": "2026-03-12", + "value": 18.9 + }, + { + "date": "2026-03-18", + "value": 20.5 + }, + { + "date": "2026-03-24", + "value": 22.1 + }, + { + "date": "2026-03-30", + "value": 23.8 + }, + { + "date": "2026-04-04", + "value": 16.4 + }, + { + "date": "2026-04-10", + "value": 18.9 + }, + { + "date": "2026-04-16", + "value": 20.5 + }, + { + "date": "2026-04-22", + "value": 22.1 + }, + { + "date": "2026-04-28", + "value": 23.8 + }, + { + "date": "2026-05-05", + "value": 16.4 + }, + { + "date": "2026-05-11", + "value": 18.0 + }, + { + "date": "2026-05-17", + "value": 19.7 + }, + { + "date": "2026-05-23", + "value": 21.3 + }, + { + "date": "2026-05-29", + "value": 23.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 13.1, + "median": 13.1, + "p10": 13.1, + "p25": 13.1, + "p75": 13.1, + "p90": 13.1, + "n": 1 + }, + { + "month": "2023-01", + "mean": 50.8, + "median": 50.8, + "p10": 50.8, + "p25": 50.8, + "p75": 50.8, + "p90": 50.8, + "n": 1 + }, + { + "month": "2023-06", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 32.8, + "median": 32.8, + "p10": 32.8, + "p25": 32.8, + "p75": 32.8, + "p90": 32.8, + "n": 1 + }, + { + "month": "2024-02", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2024-09", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2025-02", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2025-06", + "mean": 11.5, + "median": 11.5, + "p10": 11.5, + "p25": 11.5, + "p75": 11.5, + "p90": 11.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 19.5, + "median": 18.9, + "p10": 16.6, + "p25": 18.0, + "p75": 20.5, + "p90": 23.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 22.1, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 24.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 22.1, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 24.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 19.4, + "median": 19.7, + "p10": 16.1, + "p25": 18.0, + "p75": 21.3, + "p90": 22.3, + "n": 5 + }, + { + "month": "2026-01", + "mean": 22.3, + "median": 23.0, + "p10": 18.7, + "p25": 19.7, + "p75": 24.6, + "p90": 25.6, + "n": 5 + }, + { + "month": "2026-02", + "mean": 19.8, + "median": 18.9, + "p10": 16.6, + "p25": 18.0, + "p75": 22.1, + "p90": 23.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 22.6, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 26.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 20.3, + "median": 20.5, + "p10": 17.4, + "p25": 18.9, + "p75": 22.1, + "p90": 23.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 19.7, + "median": 19.7, + "p10": 17.1, + "p25": 18.0, + "p75": 21.3, + "p90": 22.3, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 39.6, + "median": 37.7, + "std": 16.2, + "min": 4.1, + "max": 106.6, + "p25": 31.6, + "p75": 44.7, + "p85": 50.0, + "p95": 71.9 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 2.624, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 28.7 + }, + { + "date": "2022-04-15", + "value": 50.8 + }, + { + "date": "2022-04-28", + "value": 14.8 + }, + { + "date": "2022-08-05", + "value": 72.2 + }, + { + "date": "2022-08-12", + "value": 34.4 + }, + { + "date": "2022-08-20", + "value": 45.1 + }, + { + "date": "2022-08-28", + "value": 24.6 + }, + { + "date": "2023-01-10", + "value": 59.0 + }, + { + "date": "2023-01-22", + "value": 20.5 + }, + { + "date": "2023-01-30", + "value": 39.4 + }, + { + "date": "2023-06-05", + "value": 12.3 + }, + { + "date": "2023-06-18", + "value": 77.9 + }, + { + "date": "2023-10-03", + "value": 106.6 + }, + { + "date": "2023-10-10", + "value": 36.9 + }, + { + "date": "2023-10-18", + "value": 31.2 + }, + { + "date": "2023-10-25", + "value": 53.3 + }, + { + "date": "2023-10-30", + "value": 18.0 + }, + { + "date": "2024-03-05", + "value": 64.0 + }, + { + "date": "2024-03-12", + "value": 4.1 + }, + { + "date": "2024-03-20", + "value": 45.1 + }, + { + "date": "2024-03-28", + "value": 32.8 + }, + { + "date": "2024-07-08", + "value": 23.0 + }, + { + "date": "2024-07-15", + "value": 69.7 + }, + { + "date": "2024-07-22", + "value": 41.0 + }, + { + "date": "2024-11-04", + "value": 90.2 + }, + { + "date": "2024-11-11", + "value": 26.2 + }, + { + "date": "2024-11-18", + "value": 55.8 + }, + { + "date": "2024-11-25", + "value": 36.9 + }, + { + "date": "2024-11-30", + "value": 75.4 + }, + { + "date": "2025-03-03", + "value": 16.4 + }, + { + "date": "2025-03-10", + "value": 47.6 + }, + { + "date": "2025-03-17", + "value": 28.7 + }, + { + "date": "2025-03-24", + "value": 34.4 + }, + { + "date": "2025-07-02", + "value": 61.5 + }, + { + "date": "2025-07-09", + "value": 9.8 + }, + { + "date": "2025-07-16", + "value": 39.4 + }, + { + "date": "2025-07-23", + "value": 49.2 + }, + { + "date": "2025-07-30", + "value": 31.2 + }, + { + "date": "2025-09-05", + "value": 40.2 + }, + { + "date": "2025-09-11", + "value": 44.3 + }, + { + "date": "2025-09-17", + "value": 27.9 + }, + { + "date": "2025-09-23", + "value": 32.0 + }, + { + "date": "2025-09-29", + "value": 34.4 + }, + { + "date": "2025-10-06", + "value": 50.0 + }, + { + "date": "2025-10-12", + "value": 33.6 + }, + { + "date": "2025-10-18", + "value": 37.7 + }, + { + "date": "2025-10-24", + "value": 40.2 + }, + { + "date": "2025-10-30", + "value": 43.5 + }, + { + "date": "2025-11-04", + "value": 29.5 + }, + { + "date": "2025-11-10", + "value": 33.6 + }, + { + "date": "2025-11-16", + "value": 36.1 + }, + { + "date": "2025-11-22", + "value": 39.4 + }, + { + "date": "2025-11-28", + "value": 42.6 + }, + { + "date": "2025-12-05", + "value": 29.5 + }, + { + "date": "2025-12-11", + "value": 32.0 + }, + { + "date": "2025-12-17", + "value": 35.3 + }, + { + "date": "2025-12-23", + "value": 38.5 + }, + { + "date": "2025-12-29", + "value": 41.8 + }, + { + "date": "2026-01-06", + "value": 38.5 + }, + { + "date": "2026-01-12", + "value": 41.0 + }, + { + "date": "2026-01-18", + "value": 44.3 + }, + { + "date": "2026-01-24", + "value": 47.6 + }, + { + "date": "2026-01-30", + "value": 32.0 + }, + { + "date": "2026-02-04", + "value": 36.9 + }, + { + "date": "2026-02-10", + "value": 40.2 + }, + { + "date": "2026-02-16", + "value": 44.3 + }, + { + "date": "2026-02-22", + "value": 27.9 + }, + { + "date": "2026-02-28", + "value": 32.0 + }, + { + "date": "2026-03-05", + "value": 45.9 + }, + { + "date": "2026-03-11", + "value": 50.0 + }, + { + "date": "2026-03-17", + "value": 33.6 + }, + { + "date": "2026-03-23", + "value": 37.7 + }, + { + "date": "2026-03-29", + "value": 40.2 + }, + { + "date": "2026-04-06", + "value": 45.9 + }, + { + "date": "2026-04-12", + "value": 29.5 + }, + { + "date": "2026-04-18", + "value": 33.6 + }, + { + "date": "2026-04-24", + "value": 36.1 + }, + { + "date": "2026-04-30", + "value": 39.4 + }, + { + "date": "2026-05-04", + "value": 26.2 + }, + { + "date": "2026-05-10", + "value": 29.5 + }, + { + "date": "2026-05-16", + "value": 32.0 + }, + { + "date": "2026-05-22", + "value": 35.3 + }, + { + "date": "2026-05-28", + "value": 38.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 31.4, + "median": 28.7, + "p10": 17.5, + "p25": 21.7, + "p75": 39.8, + "p90": 46.4, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 44.1, + "median": 39.8, + "p10": 27.6, + "p25": 32.0, + "p75": 51.9, + "p90": 64.0, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 39.6, + "median": 39.4, + "p10": 24.3, + "p25": 29.9, + "p75": 49.2, + "p90": 55.1, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 45.1, + "median": 45.1, + "p10": 18.9, + "p25": 28.7, + "p75": 61.5, + "p90": 71.3, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 49.2, + "median": 36.9, + "p10": 23.3, + "p25": 31.2, + "p75": 53.3, + "p90": 85.3, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 36.5, + "median": 38.9, + "p10": 12.7, + "p25": 25.7, + "p75": 49.9, + "p90": 58.3, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 44.5, + "median": 41.0, + "p10": 26.6, + "p25": 32.0, + "p75": 55.3, + "p90": 64.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 56.9, + "median": 55.8, + "p10": 30.5, + "p25": 36.9, + "p75": 75.4, + "p90": 84.3, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 31.8, + "median": 31.6, + "p10": 20.1, + "p25": 25.7, + "p75": 37.7, + "p90": 43.6, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 38.2, + "median": 39.4, + "p10": 18.4, + "p25": 31.2, + "p75": 49.2, + "p90": 56.6, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 35.8, + "median": 34.4, + "p10": 29.5, + "p25": 32.0, + "p75": 40.2, + "p90": 42.6, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 41.0, + "median": 40.2, + "p10": 35.3, + "p25": 37.7, + "p75": 43.5, + "p90": 47.4, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 36.2, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 35.4, + "median": 35.3, + "p10": 30.5, + "p25": 32.0, + "p75": 38.5, + "p90": 40.5, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 40.7, + "median": 41.0, + "p10": 34.6, + "p25": 38.5, + "p75": 44.3, + "p90": 46.2, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 36.2, + "median": 36.9, + "p10": 29.5, + "p25": 32.0, + "p75": 40.2, + "p90": 42.6, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 41.5, + "median": 40.2, + "p10": 35.3, + "p25": 37.7, + "p75": 45.9, + "p90": 48.4, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 36.9, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 39.4, + "p90": 43.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 32.3, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 35.3, + "p90": 37.2, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 30.0, + "median": 27.9, + "std": 13.0, + "min": 2.5, + "max": 80.4, + "p25": 23.0, + "p75": 33.6, + "p85": 36.9, + "p95": 56.7 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 1.476, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 23.0 + }, + { + "date": "2022-05-10", + "value": 36.9 + }, + { + "date": "2022-05-18", + "value": 9.8 + }, + { + "date": "2022-05-25", + "value": 50.8 + }, + { + "date": "2023-02-06", + "value": 27.1 + }, + { + "date": "2023-02-14", + "value": 64.0 + }, + { + "date": "2023-02-22", + "value": 16.4 + }, + { + "date": "2023-02-28", + "value": 45.1 + }, + { + "date": "2023-09-05", + "value": 6.6 + }, + { + "date": "2023-09-15", + "value": 34.4 + }, + { + "date": "2023-09-25", + "value": 53.3 + }, + { + "date": "2024-04-03", + "value": 31.2 + }, + { + "date": "2024-04-10", + "value": 12.3 + }, + { + "date": "2024-04-17", + "value": 59.0 + }, + { + "date": "2024-04-24", + "value": 20.5 + }, + { + "date": "2024-10-02", + "value": 39.4 + }, + { + "date": "2024-10-09", + "value": 2.5 + }, + { + "date": "2024-10-16", + "value": 69.7 + }, + { + "date": "2024-10-23", + "value": 24.6 + }, + { + "date": "2024-10-30", + "value": 45.1 + }, + { + "date": "2025-04-07", + "value": 18.0 + }, + { + "date": "2025-04-14", + "value": 32.8 + }, + { + "date": "2025-04-21", + "value": 80.4 + }, + { + "date": "2025-04-28", + "value": 14.8 + }, + { + "date": "2025-09-04", + "value": 32.0 + }, + { + "date": "2025-09-10", + "value": 33.6 + }, + { + "date": "2025-09-16", + "value": 36.9 + }, + { + "date": "2025-09-22", + "value": 24.6 + }, + { + "date": "2025-09-28", + "value": 27.9 + }, + { + "date": "2025-10-05", + "value": 31.2 + }, + { + "date": "2025-10-11", + "value": 33.6 + }, + { + "date": "2025-10-17", + "value": 22.1 + }, + { + "date": "2025-10-23", + "value": 24.6 + }, + { + "date": "2025-10-29", + "value": 26.2 + }, + { + "date": "2025-11-06", + "value": 31.2 + }, + { + "date": "2025-11-12", + "value": 18.9 + }, + { + "date": "2025-11-18", + "value": 22.1 + }, + { + "date": "2025-11-24", + "value": 23.8 + }, + { + "date": "2025-11-30", + "value": 26.2 + }, + { + "date": "2025-12-04", + "value": 23.0 + }, + { + "date": "2025-12-10", + "value": 26.2 + }, + { + "date": "2025-12-16", + "value": 27.9 + }, + { + "date": "2025-12-22", + "value": 30.3 + }, + { + "date": "2025-12-28", + "value": 32.8 + }, + { + "date": "2026-01-05", + "value": 23.0 + }, + { + "date": "2026-01-11", + "value": 25.4 + }, + { + "date": "2026-01-17", + "value": 27.1 + }, + { + "date": "2026-01-23", + "value": 29.5 + }, + { + "date": "2026-01-29", + "value": 32.0 + }, + { + "date": "2026-02-06", + "value": 29.5 + }, + { + "date": "2026-02-12", + "value": 32.0 + }, + { + "date": "2026-02-18", + "value": 33.6 + }, + { + "date": "2026-02-24", + "value": 36.9 + }, + { + "date": "2026-02-30", + "value": 24.6 + }, + { + "date": "2026-03-04", + "value": 28.7 + }, + { + "date": "2026-03-10", + "value": 31.2 + }, + { + "date": "2026-03-16", + "value": 33.6 + }, + { + "date": "2026-03-22", + "value": 22.1 + }, + { + "date": "2026-03-28", + "value": 24.6 + }, + { + "date": "2026-04-05", + "value": 27.9 + }, + { + "date": "2026-04-11", + "value": 31.2 + }, + { + "date": "2026-04-17", + "value": 18.9 + }, + { + "date": "2026-04-23", + "value": 22.1 + }, + { + "date": "2026-04-29", + "value": 23.8 + }, + { + "date": "2026-05-06", + "value": 35.3 + }, + { + "date": "2026-05-12", + "value": 23.0 + }, + { + "date": "2026-05-18", + "value": 26.2 + }, + { + "date": "2026-05-24", + "value": 27.9 + }, + { + "date": "2026-05-30", + "value": 30.3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 30.2, + "median": 29.9, + "p10": 13.8, + "p25": 19.7, + "p75": 40.4, + "p90": 46.7, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 38.1, + "median": 36.1, + "p10": 19.6, + "p25": 24.4, + "p75": 49.9, + "p90": 58.3, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 31.4, + "median": 34.4, + "p10": 12.1, + "p25": 20.5, + "p75": 43.9, + "p90": 49.5, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 30.7, + "median": 25.8, + "p10": 14.8, + "p25": 18.4, + "p75": 38.1, + "p90": 50.7, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 36.2, + "median": 39.4, + "p10": 11.3, + "p25": 24.6, + "p75": 45.1, + "p90": 59.9, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 36.5, + "median": 25.4, + "p10": 15.7, + "p25": 17.2, + "p75": 44.7, + "p90": 66.1, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 31.0, + "median": 32.0, + "p10": 25.9, + "p25": 27.9, + "p75": 33.6, + "p90": 35.6, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 27.6, + "median": 26.2, + "p10": 23.1, + "p25": 24.6, + "p75": 31.2, + "p90": 32.6, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 24.4, + "median": 23.8, + "p10": 20.2, + "p25": 22.1, + "p75": 26.2, + "p90": 29.2, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 28.0, + "median": 27.9, + "p10": 24.3, + "p25": 26.2, + "p75": 30.3, + "p90": 31.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 27.4, + "median": 27.1, + "p10": 23.9, + "p25": 25.4, + "p75": 29.5, + "p90": 31.0, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 31.3, + "median": 32.0, + "p10": 26.6, + "p25": 29.5, + "p75": 33.6, + "p90": 35.6, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 28.0, + "median": 28.7, + "p10": 23.1, + "p25": 24.6, + "p75": 31.2, + "p90": 32.6, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 24.8, + "median": 23.8, + "p10": 20.2, + "p25": 22.1, + "p75": 27.9, + "p90": 29.8, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 28.5, + "median": 27.9, + "p10": 24.3, + "p25": 26.2, + "p75": 30.3, + "p90": 33.3, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 36.0, + "median": 33.6, + "std": 15.7, + "min": 3.3, + "max": 94.3, + "p25": 28.1, + "p75": 41.0, + "p85": 44.3, + "p95": 67.2 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 4.51, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 32.8 + }, + { + "date": "2022-06-15", + "value": 18.0 + }, + { + "date": "2022-06-25", + "value": 55.8 + }, + { + "date": "2023-03-08", + "value": 3.3 + }, + { + "date": "2023-03-15", + "value": 45.1 + }, + { + "date": "2023-03-22", + "value": 94.3 + }, + { + "date": "2023-03-29", + "value": 24.6 + }, + { + "date": "2023-11-06", + "value": 50.8 + }, + { + "date": "2023-11-13", + "value": 14.8 + }, + { + "date": "2023-11-20", + "value": 69.7 + }, + { + "date": "2024-06-03", + "value": 28.7 + }, + { + "date": "2024-06-10", + "value": 59.0 + }, + { + "date": "2024-06-17", + "value": 8.2 + }, + { + "date": "2024-06-24", + "value": 39.4 + }, + { + "date": "2024-06-30", + "value": 77.9 + }, + { + "date": "2025-01-07", + "value": 23.0 + }, + { + "date": "2025-01-14", + "value": 42.6 + }, + { + "date": "2025-01-21", + "value": 12.3 + }, + { + "date": "2025-01-28", + "value": 64.0 + }, + { + "date": "2025-08-04", + "value": 34.4 + }, + { + "date": "2025-08-08", + "value": 6.6 + }, + { + "date": "2025-08-12", + "value": 53.3 + }, + { + "date": "2025-08-16", + "value": 27.1 + }, + { + "date": "2025-08-20", + "value": 82.0 + }, + { + "date": "2025-08-24", + "value": 16.4 + }, + { + "date": "2025-09-06", + "value": 33.6 + }, + { + "date": "2025-09-12", + "value": 36.9 + }, + { + "date": "2025-09-18", + "value": 39.4 + }, + { + "date": "2025-09-24", + "value": 42.6 + }, + { + "date": "2025-09-30", + "value": 27.9 + }, + { + "date": "2025-10-04", + "value": 32.8 + }, + { + "date": "2025-10-10", + "value": 36.1 + }, + { + "date": "2025-10-16", + "value": 39.4 + }, + { + "date": "2025-10-22", + "value": 24.6 + }, + { + "date": "2025-10-28", + "value": 27.9 + }, + { + "date": "2025-11-05", + "value": 41.0 + }, + { + "date": "2025-11-11", + "value": 44.3 + }, + { + "date": "2025-11-17", + "value": 29.5 + }, + { + "date": "2025-11-23", + "value": 33.6 + }, + { + "date": "2025-11-29", + "value": 36.1 + }, + { + "date": "2025-12-06", + "value": 41.0 + }, + { + "date": "2025-12-12", + "value": 26.2 + }, + { + "date": "2025-12-18", + "value": 29.5 + }, + { + "date": "2025-12-24", + "value": 32.0 + }, + { + "date": "2025-12-30", + "value": 35.3 + }, + { + "date": "2026-01-04", + "value": 23.0 + }, + { + "date": "2026-01-10", + "value": 26.2 + }, + { + "date": "2026-01-16", + "value": 28.7 + }, + { + "date": "2026-01-22", + "value": 31.2 + }, + { + "date": "2026-01-28", + "value": 34.4 + }, + { + "date": "2026-02-05", + "value": 32.0 + }, + { + "date": "2026-02-11", + "value": 33.6 + }, + { + "date": "2026-02-17", + "value": 36.9 + }, + { + "date": "2026-02-23", + "value": 39.4 + }, + { + "date": "2026-02-29", + "value": 42.6 + }, + { + "date": "2026-03-06", + "value": 30.3 + }, + { + "date": "2026-03-12", + "value": 32.8 + }, + { + "date": "2026-03-18", + "value": 36.1 + }, + { + "date": "2026-03-24", + "value": 39.4 + }, + { + "date": "2026-03-30", + "value": 24.6 + }, + { + "date": "2026-04-04", + "value": 38.5 + }, + { + "date": "2026-04-10", + "value": 41.0 + }, + { + "date": "2026-04-16", + "value": 44.3 + }, + { + "date": "2026-04-22", + "value": 29.5 + }, + { + "date": "2026-04-28", + "value": 33.6 + }, + { + "date": "2026-05-05", + "value": 37.7 + }, + { + "date": "2026-05-11", + "value": 41.0 + }, + { + "date": "2026-05-17", + "value": 26.2 + }, + { + "date": "2026-05-23", + "value": 29.5 + }, + { + "date": "2026-05-29", + "value": 32.0 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 35.5, + "median": 32.8, + "p10": 21.0, + "p25": 25.4, + "p75": 44.3, + "p90": 51.2, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 41.8, + "median": 34.9, + "p10": 9.7, + "p25": 19.3, + "p75": 57.4, + "p90": 79.5, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 45.1, + "median": 50.8, + "p10": 22.0, + "p25": 32.8, + "p75": 60.3, + "p90": 65.9, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 42.6, + "median": 39.4, + "p10": 16.4, + "p25": 28.7, + "p75": 59.0, + "p90": 70.4, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 35.5, + "median": 32.8, + "p10": 15.5, + "p25": 20.3, + "p75": 48.0, + "p90": 57.6, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 36.7, + "median": 30.7, + "p10": 11.5, + "p25": 19.1, + "p75": 48.6, + "p90": 67.6, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 36.1, + "median": 36.9, + "p10": 30.2, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 32.1, + "median": 32.8, + "p10": 25.9, + "p25": 27.9, + "p75": 36.1, + "p90": 38.0, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 36.9, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 41.0, + "p90": 43.0, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 32.8, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 35.3, + "p90": 38.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 28.7, + "median": 28.7, + "p10": 24.3, + "p25": 26.2, + "p75": 31.2, + "p90": 33.1, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 36.9, + "median": 36.9, + "p10": 32.6, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 32.6, + "median": 32.8, + "p10": 26.9, + "p25": 30.3, + "p75": 36.1, + "p90": 38.0, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 37.4, + "median": 38.5, + "p10": 31.2, + "p25": 33.6, + "p75": 41.0, + "p90": 43.0, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 33.3, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 37.7, + "p90": 39.7, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 3.6, + "median": 3.3, + "std": 1.5, + "min": 0.8, + "max": 11.5, + "p25": 2.7, + "p75": 4.1, + "p85": 4.1, + "p95": 5.4 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 2.5 + }, + { + "date": "2022-07-05", + "value": 4.1 + }, + { + "date": "2022-10-12", + "value": 1.6 + }, + { + "date": "2023-01-20", + "value": 5.7 + }, + { + "date": "2023-04-15", + "value": 3.3 + }, + { + "date": "2023-07-28", + "value": 4.9 + }, + { + "date": "2023-10-05", + "value": 2.5 + }, + { + "date": "2024-01-12", + "value": 11.5 + }, + { + "date": "2024-04-22", + "value": 3.3 + }, + { + "date": "2024-07-10", + "value": 6.6 + }, + { + "date": "2024-10-18", + "value": 2.5 + }, + { + "date": "2025-01-25", + "value": 4.1 + }, + { + "date": "2025-05-08", + "value": 0.8 + }, + { + "date": "2025-08-15", + "value": 4.9 + }, + { + "date": "2025-09-04", + "value": 2.5 + }, + { + "date": "2025-09-10", + "value": 3.3 + }, + { + "date": "2025-09-16", + "value": 3.3 + }, + { + "date": "2025-09-22", + "value": 3.3 + }, + { + "date": "2025-10-05", + "value": 2.5 + }, + { + "date": "2025-10-11", + "value": 3.3 + }, + { + "date": "2025-10-17", + "value": 3.3 + }, + { + "date": "2025-10-23", + "value": 3.3 + }, + { + "date": "2025-11-06", + "value": 3.3 + }, + { + "date": "2025-11-12", + "value": 4.1 + }, + { + "date": "2025-11-18", + "value": 4.1 + }, + { + "date": "2025-11-24", + "value": 4.1 + }, + { + "date": "2025-12-04", + "value": 3.3 + }, + { + "date": "2025-12-10", + "value": 4.1 + }, + { + "date": "2025-12-16", + "value": 4.1 + }, + { + "date": "2025-12-22", + "value": 2.5 + }, + { + "date": "2026-01-05", + "value": 3.3 + }, + { + "date": "2026-01-11", + "value": 4.1 + }, + { + "date": "2026-01-17", + "value": 2.5 + }, + { + "date": "2026-01-23", + "value": 2.5 + }, + { + "date": "2026-02-06", + "value": 4.1 + }, + { + "date": "2026-02-12", + "value": 2.5 + }, + { + "date": "2026-02-18", + "value": 3.3 + }, + { + "date": "2026-02-24", + "value": 3.3 + }, + { + "date": "2026-03-04", + "value": 2.5 + }, + { + "date": "2026-03-10", + "value": 2.5 + }, + { + "date": "2026-03-16", + "value": 3.3 + }, + { + "date": "2026-03-22", + "value": 3.3 + }, + { + "date": "2026-04-05", + "value": 3.3 + }, + { + "date": "2026-04-11", + "value": 3.3 + }, + { + "date": "2026-04-17", + "value": 4.1 + }, + { + "date": "2026-04-23", + "value": 4.1 + }, + { + "date": "2026-05-06", + "value": 3.3 + }, + { + "date": "2026-05-12", + "value": 3.3 + }, + { + "date": "2026-05-18", + "value": 4.1 + }, + { + "date": "2026-05-24", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-10", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2023-10", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 11.5, + "median": 11.5, + "p10": 11.5, + "p25": 11.5, + "p75": 11.5, + "p90": 11.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2024-10", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-05", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.9, + "median": 4.1, + "p10": 3.5, + "p25": 3.9, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.5, + "median": 3.7, + "p10": 2.7, + "p25": 3.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.1, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.5, + "p90": 3.9, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.3, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.5, + "p90": 3.9, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.7, + "median": 3.7, + "p10": 3.3, + "p25": 3.3, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.7, + "median": 3.7, + "p10": 3.3, + "p25": 3.3, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 14.3, + "median": 13.1, + "std": 7.4, + "min": 1.6, + "max": 45.1, + "p25": 10.7, + "p75": 15.6, + "p85": 16.7, + "p95": 30.3 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 10.25, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 9.8 + }, + { + "date": "2022-05-15", + "value": 20.5 + }, + { + "date": "2022-05-22", + "value": 6.6 + }, + { + "date": "2022-11-03", + "value": 28.7 + }, + { + "date": "2022-11-10", + "value": 12.3 + }, + { + "date": "2022-11-18", + "value": 4.1 + }, + { + "date": "2022-11-25", + "value": 18.0 + }, + { + "date": "2023-05-08", + "value": 14.8 + }, + { + "date": "2023-05-15", + "value": 32.8 + }, + { + "date": "2023-05-22", + "value": 8.2 + }, + { + "date": "2023-11-06", + "value": 45.1 + }, + { + "date": "2023-11-13", + "value": 1.6 + }, + { + "date": "2023-11-20", + "value": 23.0 + }, + { + "date": "2023-11-27", + "value": 12.3 + }, + { + "date": "2023-11-30", + "value": 6.6 + }, + { + "date": "2024-05-06", + "value": 16.4 + }, + { + "date": "2024-05-13", + "value": 36.9 + }, + { + "date": "2024-05-20", + "value": 9.8 + }, + { + "date": "2024-05-27", + "value": 2.5 + }, + { + "date": "2024-11-04", + "value": 14.8 + }, + { + "date": "2024-11-11", + "value": 24.6 + }, + { + "date": "2024-11-18", + "value": 6.6 + }, + { + "date": "2025-05-05", + "value": 18.0 + }, + { + "date": "2025-05-09", + "value": 28.7 + }, + { + "date": "2025-05-13", + "value": 4.1 + }, + { + "date": "2025-05-17", + "value": 12.3 + }, + { + "date": "2025-05-21", + "value": 34.4 + }, + { + "date": "2025-05-25", + "value": 8.2 + }, + { + "date": "2025-09-05", + "value": 11.5 + }, + { + "date": "2025-09-11", + "value": 13.1 + }, + { + "date": "2025-09-17", + "value": 13.9 + }, + { + "date": "2025-09-23", + "value": 14.8 + }, + { + "date": "2025-09-29", + "value": 15.6 + }, + { + "date": "2025-10-06", + "value": 11.5 + }, + { + "date": "2025-10-12", + "value": 12.3 + }, + { + "date": "2025-10-18", + "value": 13.1 + }, + { + "date": "2025-10-24", + "value": 14.8 + }, + { + "date": "2025-10-30", + "value": 9.0 + }, + { + "date": "2025-11-04", + "value": 14.8 + }, + { + "date": "2025-11-10", + "value": 15.6 + }, + { + "date": "2025-11-16", + "value": 16.4 + }, + { + "date": "2025-11-22", + "value": 11.5 + }, + { + "date": "2025-11-28", + "value": 12.3 + }, + { + "date": "2025-12-05", + "value": 13.9 + }, + { + "date": "2025-12-11", + "value": 15.6 + }, + { + "date": "2025-12-17", + "value": 9.8 + }, + { + "date": "2025-12-23", + "value": 11.5 + }, + { + "date": "2025-12-29", + "value": 12.3 + }, + { + "date": "2026-01-06", + "value": 13.9 + }, + { + "date": "2026-01-12", + "value": 9.0 + }, + { + "date": "2026-01-18", + "value": 9.8 + }, + { + "date": "2026-01-24", + "value": 10.7 + }, + { + "date": "2026-01-30", + "value": 11.5 + }, + { + "date": "2026-02-04", + "value": 10.7 + }, + { + "date": "2026-02-10", + "value": 11.5 + }, + { + "date": "2026-02-16", + "value": 13.1 + }, + { + "date": "2026-02-22", + "value": 13.9 + }, + { + "date": "2026-02-28", + "value": 14.8 + }, + { + "date": "2026-03-05", + "value": 10.7 + }, + { + "date": "2026-03-11", + "value": 11.5 + }, + { + "date": "2026-03-17", + "value": 12.3 + }, + { + "date": "2026-03-23", + "value": 13.1 + }, + { + "date": "2026-03-29", + "value": 14.8 + }, + { + "date": "2026-04-06", + "value": 13.1 + }, + { + "date": "2026-04-12", + "value": 14.8 + }, + { + "date": "2026-04-18", + "value": 15.6 + }, + { + "date": "2026-04-24", + "value": 16.4 + }, + { + "date": "2026-04-30", + "value": 11.5 + }, + { + "date": "2026-05-04", + "value": 13.1 + }, + { + "date": "2026-05-10", + "value": 13.9 + }, + { + "date": "2026-05-16", + "value": 15.6 + }, + { + "date": "2026-05-22", + "value": 9.8 + }, + { + "date": "2026-05-28", + "value": 11.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 12.3, + "median": 9.8, + "p10": 7.2, + "p25": 8.2, + "p75": 15.2, + "p90": 18.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 15.8, + "median": 15.2, + "p10": 6.6, + "p25": 10.2, + "p75": 20.7, + "p90": 25.5, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 18.6, + "median": 14.8, + "p10": 9.5, + "p25": 11.5, + "p75": 23.8, + "p90": 29.2, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 17.7, + "median": 12.3, + "p10": 3.6, + "p25": 6.6, + "p75": 23.0, + "p90": 36.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 16.4, + "median": 13.1, + "p10": 4.7, + "p25": 8.0, + "p75": 21.6, + "p90": 30.7, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 15.3, + "median": 14.8, + "p10": 8.2, + "p25": 10.7, + "p75": 19.7, + "p90": 22.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 17.6, + "median": 15.2, + "p10": 6.1, + "p25": 9.3, + "p75": 26.1, + "p90": 31.6, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 13.8, + "median": 13.9, + "p10": 12.1, + "p25": 13.1, + "p75": 14.8, + "p90": 15.3, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 12.1, + "median": 12.3, + "p10": 10.0, + "p25": 11.5, + "p75": 13.1, + "p90": 14.1, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 14.1, + "median": 14.8, + "p10": 11.8, + "p25": 12.3, + "p75": 15.6, + "p90": 16.1, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 12.6, + "median": 12.3, + "p10": 10.5, + "p25": 11.5, + "p75": 13.9, + "p90": 14.9, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 11.0, + "median": 10.7, + "p10": 9.3, + "p25": 9.8, + "p75": 11.5, + "p90": 13.0, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 12.8, + "median": 13.1, + "p10": 11.0, + "p25": 11.5, + "p75": 13.9, + "p90": 14.4, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 12.5, + "median": 12.3, + "p10": 11.0, + "p25": 11.5, + "p75": 13.1, + "p90": 14.1, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 14.3, + "median": 14.8, + "p10": 12.1, + "p25": 13.1, + "p75": 15.6, + "p90": 16.1, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 12.8, + "median": 13.1, + "p10": 10.5, + "p25": 11.5, + "p75": 13.9, + "p90": 14.9, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 2.6, + "median": 2.5, + "std": 1.1, + "min": 0.0, + "max": 8.2, + "p25": 2.5, + "p75": 3.3, + "p85": 3.3, + "p95": 4.3 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 1.6 + }, + { + "date": "2022-06-10", + "value": 2.5 + }, + { + "date": "2022-07-15", + "value": 0.8 + }, + { + "date": "2022-08-22", + "value": 3.3 + }, + { + "date": "2022-10-05", + "value": 1.6 + }, + { + "date": "2022-11-18", + "value": 4.1 + }, + { + "date": "2023-01-10", + "value": 2.5 + }, + { + "date": "2023-03-25", + "value": 5.7 + }, + { + "date": "2023-05-12", + "value": 1.6 + }, + { + "date": "2023-07-08", + "value": 3.3 + }, + { + "date": "2023-09-15", + "value": 0.8 + }, + { + "date": "2023-11-22", + "value": 2.5 + }, + { + "date": "2024-01-18", + "value": 8.2 + }, + { + "date": "2024-03-08", + "value": 2.5 + }, + { + "date": "2024-05-15", + "value": 1.6 + }, + { + "date": "2024-07-22", + "value": 4.1 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 3.3 + }, + { + "date": "2025-01-15", + "value": 2.5 + }, + { + "date": "2025-03-20", + "value": 1.6 + }, + { + "date": "2025-05-28", + "value": 4.9 + }, + { + "date": "2025-08-05", + "value": 2.5 + }, + { + "date": "2025-09-05", + "value": 3.3 + }, + { + "date": "2025-09-11", + "value": 3.3 + }, + { + "date": "2025-09-17", + "value": 2.5 + }, + { + "date": "2025-09-23", + "value": 2.5 + }, + { + "date": "2025-10-06", + "value": 3.3 + }, + { + "date": "2025-10-12", + "value": 1.6 + }, + { + "date": "2025-10-18", + "value": 2.5 + }, + { + "date": "2025-10-24", + "value": 2.5 + }, + { + "date": "2025-11-04", + "value": 1.6 + }, + { + "date": "2025-11-10", + "value": 1.6 + }, + { + "date": "2025-11-16", + "value": 2.5 + }, + { + "date": "2025-11-22", + "value": 2.5 + }, + { + "date": "2025-12-05", + "value": 2.5 + }, + { + "date": "2025-12-11", + "value": 2.5 + }, + { + "date": "2025-12-17", + "value": 2.5 + }, + { + "date": "2025-12-23", + "value": 3.3 + }, + { + "date": "2026-01-06", + "value": 2.5 + }, + { + "date": "2026-01-12", + "value": 2.5 + }, + { + "date": "2026-01-18", + "value": 2.5 + }, + { + "date": "2026-01-24", + "value": 3.3 + }, + { + "date": "2026-02-04", + "value": 3.3 + }, + { + "date": "2026-02-10", + "value": 3.3 + }, + { + "date": "2026-02-16", + "value": 3.3 + }, + { + "date": "2026-02-22", + "value": 2.5 + }, + { + "date": "2026-03-05", + "value": 2.5 + }, + { + "date": "2026-03-11", + "value": 3.3 + }, + { + "date": "2026-03-17", + "value": 1.6 + }, + { + "date": "2026-03-23", + "value": 2.5 + }, + { + "date": "2026-04-06", + "value": 2.5 + }, + { + "date": "2026-04-12", + "value": 1.6 + }, + { + "date": "2026-04-18", + "value": 1.6 + }, + { + "date": "2026-04-24", + "value": 2.5 + }, + { + "date": "2026-05-04", + "value": 2.5 + }, + { + "date": "2026-05-10", + "value": 2.5 + }, + { + "date": "2026-05-16", + "value": 2.5 + }, + { + "date": "2026-05-22", + "value": 2.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-06", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2022-10", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-07", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-09", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2023-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1 + }, + { + "month": "2024-03", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2024-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2025-05", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2025-08", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-10", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.0, + "median": 2.0, + "p10": 1.6, + "p25": 1.6, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.0, + "median": 2.0, + "p10": 1.6, + "p25": 1.6, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 2.8, + "median": 2.5, + "std": 1.5, + "min": 0.0, + "max": 10.7, + "p25": 2.5, + "p75": 3.3, + "p85": 3.3, + "p95": 5.1 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 1.6 + }, + { + "date": "2022-06-13", + "value": 0.8 + }, + { + "date": "2022-07-16", + "value": 2.5 + }, + { + "date": "2022-08-26", + "value": 1.6 + }, + { + "date": "2022-10-07", + "value": 4.1 + }, + { + "date": "2022-11-23", + "value": 1.6 + }, + { + "date": "2023-01-13", + "value": 3.3 + }, + { + "date": "2023-04-01", + "value": 2.5 + }, + { + "date": "2023-05-14", + "value": 4.9 + }, + { + "date": "2023-07-12", + "value": 1.6 + }, + { + "date": "2023-09-16", + "value": 10.7 + }, + { + "date": "2023-11-25", + "value": 2.5 + }, + { + "date": "2024-01-28", + "value": 5.7 + }, + { + "date": "2024-03-11", + "value": 0.8 + }, + { + "date": "2024-05-17", + "value": 3.3 + }, + { + "date": "2024-07-27", + "value": 4.1 + }, + { + "date": "2024-09-10", + "value": 1.6 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 2.5 + }, + { + "date": "2025-03-22", + "value": 6.6 + }, + { + "date": "2025-06-03", + "value": 1.6 + }, + { + "date": "2025-08-08", + "value": 4.1 + }, + { + "date": "2025-09-04", + "value": 1.6 + }, + { + "date": "2025-09-10", + "value": 2.5 + }, + { + "date": "2025-09-16", + "value": 2.5 + }, + { + "date": "2025-09-22", + "value": 2.5 + }, + { + "date": "2025-10-05", + "value": 2.5 + }, + { + "date": "2025-10-11", + "value": 2.5 + }, + { + "date": "2025-10-17", + "value": 3.3 + }, + { + "date": "2025-10-23", + "value": 3.3 + }, + { + "date": "2025-11-06", + "value": 2.5 + }, + { + "date": "2025-11-12", + "value": 2.5 + }, + { + "date": "2025-11-18", + "value": 2.5 + }, + { + "date": "2025-11-24", + "value": 3.3 + }, + { + "date": "2025-12-04", + "value": 2.5 + }, + { + "date": "2025-12-10", + "value": 2.5 + }, + { + "date": "2025-12-16", + "value": 2.5 + }, + { + "date": "2025-12-22", + "value": 1.6 + }, + { + "date": "2026-01-05", + "value": 3.3 + }, + { + "date": "2026-01-11", + "value": 3.3 + }, + { + "date": "2026-01-17", + "value": 2.5 + }, + { + "date": "2026-01-23", + "value": 2.5 + }, + { + "date": "2026-02-06", + "value": 3.3 + }, + { + "date": "2026-02-12", + "value": 1.6 + }, + { + "date": "2026-02-18", + "value": 2.5 + }, + { + "date": "2026-02-24", + "value": 2.5 + }, + { + "date": "2026-03-04", + "value": 2.5 + }, + { + "date": "2026-03-10", + "value": 2.5 + }, + { + "date": "2026-03-16", + "value": 2.5 + }, + { + "date": "2026-03-22", + "value": 3.3 + }, + { + "date": "2026-04-05", + "value": 2.5 + }, + { + "date": "2026-04-11", + "value": 2.5 + }, + { + "date": "2026-04-17", + "value": 2.5 + }, + { + "date": "2026-04-23", + "value": 2.5 + }, + { + "date": "2026-05-06", + "value": 2.5 + }, + { + "date": "2026-05-12", + "value": 2.5 + }, + { + "date": "2026-05-18", + "value": 2.5 + }, + { + "date": "2026-05-24", + "value": 2.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-06", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2022-07", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-08", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-11", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2023-07", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-09", + "mean": 10.7, + "median": 10.7, + "p10": 10.7, + "p25": 10.7, + "p75": 10.7, + "p90": 10.7, + "n": 1 + }, + { + "month": "2023-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2024-03", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2024-05", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-09", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2025-06", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.3, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.3, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-01", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-02", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 10.4, + "median": 9.8, + "std": 4.6, + "min": 1.6, + "max": 34.4, + "p25": 8.2, + "p75": 11.5, + "p85": 12.3, + "p95": 16.7 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 23.37, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 6.6 + }, + { + "date": "2023-03-25", + "value": 18.0 + }, + { + "date": "2023-09-20", + "value": 34.4 + }, + { + "date": "2024-03-15", + "value": 4.9 + }, + { + "date": "2024-03-28", + "value": 14.8 + }, + { + "date": "2024-09-05", + "value": 23.0 + }, + { + "date": "2024-09-15", + "value": 9.8 + }, + { + "date": "2024-09-25", + "value": 1.6 + }, + { + "date": "2025-03-10", + "value": 12.3 + }, + { + "date": "2025-03-22", + "value": 4.1 + }, + { + "date": "2025-07-08", + "value": 16.4 + }, + { + "date": "2025-07-22", + "value": 3.3 + }, + { + "date": "2025-09-05", + "value": 11.5 + }, + { + "date": "2025-09-11", + "value": 12.3 + }, + { + "date": "2025-09-17", + "value": 8.2 + }, + { + "date": "2025-09-23", + "value": 9.0 + }, + { + "date": "2025-09-29", + "value": 9.8 + }, + { + "date": "2025-10-06", + "value": 11.5 + }, + { + "date": "2025-10-12", + "value": 6.6 + }, + { + "date": "2025-10-18", + "value": 8.2 + }, + { + "date": "2025-10-24", + "value": 9.0 + }, + { + "date": "2025-10-30", + "value": 9.0 + }, + { + "date": "2025-11-04", + "value": 8.2 + }, + { + "date": "2025-11-10", + "value": 9.8 + }, + { + "date": "2025-11-16", + "value": 9.8 + }, + { + "date": "2025-11-22", + "value": 10.7 + }, + { + "date": "2025-11-28", + "value": 11.5 + }, + { + "date": "2025-12-05", + "value": 8.2 + }, + { + "date": "2025-12-11", + "value": 9.0 + }, + { + "date": "2025-12-17", + "value": 9.8 + }, + { + "date": "2025-12-23", + "value": 10.7 + }, + { + "date": "2025-12-29", + "value": 11.5 + }, + { + "date": "2026-01-06", + "value": 10.7 + }, + { + "date": "2026-01-12", + "value": 11.5 + }, + { + "date": "2026-01-18", + "value": 12.3 + }, + { + "date": "2026-01-24", + "value": 13.1 + }, + { + "date": "2026-01-30", + "value": 9.0 + }, + { + "date": "2026-02-04", + "value": 10.7 + }, + { + "date": "2026-02-10", + "value": 11.5 + }, + { + "date": "2026-02-16", + "value": 12.3 + }, + { + "date": "2026-02-22", + "value": 8.2 + }, + { + "date": "2026-02-28", + "value": 9.0 + }, + { + "date": "2026-03-05", + "value": 10.7 + }, + { + "date": "2026-03-11", + "value": 11.5 + }, + { + "date": "2026-03-17", + "value": 6.6 + }, + { + "date": "2026-03-23", + "value": 8.2 + }, + { + "date": "2026-03-29", + "value": 9.0 + }, + { + "date": "2026-04-06", + "value": 13.1 + }, + { + "date": "2026-04-12", + "value": 8.2 + }, + { + "date": "2026-04-18", + "value": 9.8 + }, + { + "date": "2026-04-24", + "value": 9.8 + }, + { + "date": "2026-04-30", + "value": 10.7 + }, + { + "date": "2026-05-04", + "value": 7.4 + }, + { + "date": "2026-05-10", + "value": 8.2 + }, + { + "date": "2026-05-16", + "value": 9.0 + }, + { + "date": "2026-05-22", + "value": 9.8 + }, + { + "date": "2026-05-28", + "value": 10.7 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 12.3, + "median": 12.3, + "p10": 7.7, + "p25": 9.4, + "p75": 15.2, + "p90": 16.9, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 9.8, + "median": 9.8, + "p10": 5.9, + "p25": 7.4, + "p75": 12.3, + "p90": 13.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 11.5, + "median": 9.8, + "p10": 3.3, + "p25": 5.7, + "p75": 16.4, + "p90": 20.3, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 8.2, + "median": 8.2, + "p10": 4.9, + "p25": 6.1, + "p75": 10.2, + "p90": 11.5, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 9.8, + "median": 9.8, + "p10": 4.6, + "p25": 6.6, + "p75": 13.1, + "p90": 15.1, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 10.2, + "median": 9.8, + "p10": 8.5, + "p25": 9.0, + "p75": 11.5, + "p90": 12.0, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 8.9, + "median": 9.0, + "p10": 7.2, + "p25": 8.2, + "p75": 9.0, + "p90": 10.5, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 10.0, + "median": 9.8, + "p10": 8.9, + "p25": 9.8, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 9.8, + "median": 9.8, + "p10": 8.5, + "p25": 9.0, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 11.3, + "median": 11.5, + "p10": 9.7, + "p25": 10.7, + "p75": 12.3, + "p90": 12.8, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 10.3, + "median": 10.7, + "p10": 8.5, + "p25": 9.0, + "p75": 11.5, + "p90": 12.0, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 9.2, + "median": 9.0, + "p10": 7.2, + "p25": 8.2, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 10.3, + "median": 9.8, + "p10": 8.9, + "p25": 9.8, + "p75": 10.7, + "p90": 12.1, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 9.0, + "median": 9.0, + "p10": 7.7, + "p25": 8.2, + "p75": 9.8, + "p90": 10.3, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 17.1, + "median": 17.2, + "std": 3.8, + "min": 9.8, + "max": 31.2, + "p25": 15.2, + "p75": 18.9, + "p85": 20.4, + "p95": 21.8 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 14.8 + }, + { + "date": "2023-10-12", + "value": 20.5 + }, + { + "date": "2024-04-08", + "value": 9.8 + }, + { + "date": "2024-09-20", + "value": 31.2 + }, + { + "date": "2024-10-15", + "value": 16.4 + }, + { + "date": "2025-03-25", + "value": 12.3 + }, + { + "date": "2025-04-10", + "value": 23.0 + }, + { + "date": "2025-07-30", + "value": 19.7 + }, + { + "date": "2025-09-04", + "value": 13.9 + }, + { + "date": "2025-09-10", + "value": 15.6 + }, + { + "date": "2025-09-16", + "value": 17.2 + }, + { + "date": "2025-10-05", + "value": 13.9 + }, + { + "date": "2025-10-11", + "value": 15.6 + }, + { + "date": "2025-10-17", + "value": 16.4 + }, + { + "date": "2025-11-06", + "value": 18.0 + }, + { + "date": "2025-11-12", + "value": 18.9 + }, + { + "date": "2025-11-18", + "value": 20.5 + }, + { + "date": "2025-12-04", + "value": 17.2 + }, + { + "date": "2025-12-10", + "value": 18.9 + }, + { + "date": "2025-12-16", + "value": 20.5 + }, + { + "date": "2026-01-05", + "value": 17.2 + }, + { + "date": "2026-01-11", + "value": 18.9 + }, + { + "date": "2026-01-17", + "value": 11.5 + }, + { + "date": "2026-02-06", + "value": 21.3 + }, + { + "date": "2026-02-12", + "value": 13.9 + }, + { + "date": "2026-02-18", + "value": 15.6 + }, + { + "date": "2026-03-04", + "value": 12.3 + }, + { + "date": "2026-03-10", + "value": 13.9 + }, + { + "date": "2026-03-16", + "value": 15.6 + }, + { + "date": "2026-04-05", + "value": 16.4 + }, + { + "date": "2026-04-11", + "value": 18.0 + }, + { + "date": "2026-04-17", + "value": 18.9 + }, + { + "date": "2026-05-06", + "value": 16.4 + }, + { + "date": "2026-05-12", + "value": 17.2 + }, + { + "date": "2026-05-18", + "value": 18.9 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2023-10", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-10", + "mean": 16.4, + "median": 16.4, + "p10": 16.4, + "p25": 16.4, + "p75": 16.4, + "p90": 16.4, + "n": 1 + }, + { + "month": "2025-03", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2025-04", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 19.7, + "median": 19.7, + "p10": 19.7, + "p25": 19.7, + "p75": 19.7, + "p90": 19.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 15.6, + "median": 15.6, + "p10": 14.3, + "p25": 14.8, + "p75": 16.4, + "p90": 16.9, + "n": 3 + }, + { + "month": "2025-10", + "mean": 15.3, + "median": 15.6, + "p10": 14.3, + "p25": 14.8, + "p75": 16.0, + "p90": 16.2, + "n": 3 + }, + { + "month": "2025-11", + "mean": 19.1, + "median": 18.9, + "p10": 18.2, + "p25": 18.4, + "p75": 19.7, + "p90": 20.2, + "n": 3 + }, + { + "month": "2025-12", + "mean": 18.9, + "median": 18.9, + "p10": 17.5, + "p25": 18.0, + "p75": 19.7, + "p90": 20.2, + "n": 3 + }, + { + "month": "2026-01", + "mean": 15.8, + "median": 17.2, + "p10": 12.6, + "p25": 14.3, + "p75": 18.0, + "p90": 18.5, + "n": 3 + }, + { + "month": "2026-02", + "mean": 17.0, + "median": 15.6, + "p10": 14.3, + "p25": 14.8, + "p75": 18.4, + "p90": 20.2, + "n": 3 + }, + { + "month": "2026-03", + "mean": 13.9, + "median": 13.9, + "p10": 12.6, + "p25": 13.1, + "p75": 14.8, + "p90": 15.3, + "n": 3 + }, + { + "month": "2026-04", + "mean": 17.8, + "median": 18.0, + "p10": 16.7, + "p25": 17.2, + "p75": 18.4, + "p90": 18.7, + "n": 3 + }, + { + "month": "2026-05", + "mean": 17.5, + "median": 17.2, + "p10": 16.6, + "p25": 16.8, + "p75": 18.0, + "p90": 18.5, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 25.7, + "median": 25.0, + "std": 5.8, + "min": 12.3, + "max": 45.1, + "p25": 22.1, + "p75": 29.5, + "p85": 31.2, + "p95": 34.4 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 23.0 + }, + { + "date": "2022-11-30", + "value": 28.7 + }, + { + "date": "2023-03-15", + "value": 18.0 + }, + { + "date": "2023-07-10", + "value": 34.4 + }, + { + "date": "2023-10-25", + "value": 24.6 + }, + { + "date": "2024-02-08", + "value": 45.1 + }, + { + "date": "2024-05-20", + "value": 20.5 + }, + { + "date": "2024-08-12", + "value": 31.2 + }, + { + "date": "2024-11-05", + "value": 12.3 + }, + { + "date": "2025-01-22", + "value": 26.2 + }, + { + "date": "2025-04-10", + "value": 23.0 + }, + { + "date": "2025-06-18", + "value": 36.9 + }, + { + "date": "2025-07-15", + "value": 24.6 + }, + { + "date": "2025-08-05", + "value": 18.0 + }, + { + "date": "2025-09-05", + "value": 29.5 + }, + { + "date": "2025-09-10", + "value": 31.2 + }, + { + "date": "2025-09-11", + "value": 32.0 + }, + { + "date": "2025-09-17", + "value": 21.3 + }, + { + "date": "2025-10-06", + "value": 29.5 + }, + { + "date": "2025-10-12", + "value": 18.9 + }, + { + "date": "2025-10-18", + "value": 21.3 + }, + { + "date": "2025-11-04", + "value": 22.1 + }, + { + "date": "2025-11-10", + "value": 25.4 + }, + { + "date": "2025-11-16", + "value": 27.1 + }, + { + "date": "2025-12-05", + "value": 22.1 + }, + { + "date": "2025-12-11", + "value": 23.8 + }, + { + "date": "2025-12-17", + "value": 26.2 + }, + { + "date": "2026-01-06", + "value": 21.3 + }, + { + "date": "2026-01-12", + "value": 23.8 + }, + { + "date": "2026-01-18", + "value": 25.4 + }, + { + "date": "2026-02-04", + "value": 27.1 + }, + { + "date": "2026-02-10", + "value": 29.5 + }, + { + "date": "2026-02-16", + "value": 32.0 + }, + { + "date": "2026-03-05", + "value": 27.1 + }, + { + "date": "2026-03-11", + "value": 29.5 + }, + { + "date": "2026-03-17", + "value": 18.9 + }, + { + "date": "2026-04-06", + "value": 32.8 + }, + { + "date": "2026-04-12", + "value": 22.1 + }, + { + "date": "2026-04-18", + "value": 25.4 + }, + { + "date": "2026-05-04", + "value": 19.7 + }, + { + "date": "2026-05-10", + "value": 22.1 + }, + { + "date": "2026-05-16", + "value": 23.8 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2023-03", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1 + }, + { + "month": "2023-10", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2024-02", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2024-05", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-11", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 26.2, + "median": 26.2, + "p10": 26.2, + "p25": 26.2, + "p75": 26.2, + "p90": 26.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 36.9, + "median": 36.9, + "p10": 36.9, + "p25": 36.9, + "p75": 36.9, + "p90": 36.9, + "n": 1 + }, + { + "month": "2025-07", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2025-08", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 28.5, + "median": 30.3, + "p10": 23.8, + "p25": 27.5, + "p75": 31.4, + "p90": 31.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 23.2, + "median": 21.3, + "p10": 19.4, + "p25": 20.1, + "p75": 25.4, + "p90": 27.9, + "n": 3 + }, + { + "month": "2025-11", + "mean": 24.8, + "median": 25.4, + "p10": 22.8, + "p25": 23.8, + "p75": 26.2, + "p90": 26.7, + "n": 3 + }, + { + "month": "2025-12", + "mean": 24.0, + "median": 23.8, + "p10": 22.5, + "p25": 23.0, + "p75": 25.0, + "p90": 25.7, + "n": 3 + }, + { + "month": "2026-01", + "mean": 23.5, + "median": 23.8, + "p10": 21.8, + "p25": 22.5, + "p75": 24.6, + "p90": 25.1, + "n": 3 + }, + { + "month": "2026-02", + "mean": 29.5, + "median": 29.5, + "p10": 27.6, + "p25": 28.3, + "p75": 30.7, + "p90": 31.5, + "n": 3 + }, + { + "month": "2026-03", + "mean": 25.2, + "median": 27.1, + "p10": 20.5, + "p25": 23.0, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-04", + "mean": 26.8, + "median": 25.4, + "p10": 22.8, + "p25": 23.8, + "p75": 29.1, + "p90": 31.3, + "n": 3 + }, + { + "month": "2026-05", + "mean": 21.9, + "median": 22.1, + "p10": 20.2, + "p25": 20.9, + "p75": 23.0, + "p90": 23.5, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 36.9, + "median": 36.1, + "std": 11.5, + "min": 8.2, + "max": 77.9, + "p25": 29.5, + "p75": 40.2, + "p85": 43.5, + "p95": 55.4 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 23.37, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 34.4 + }, + { + "date": "2023-05-05", + "value": 53.3 + }, + { + "date": "2023-05-20", + "value": 23.0 + }, + { + "date": "2024-01-10", + "value": 77.9 + }, + { + "date": "2024-01-25", + "value": 28.7 + }, + { + "date": "2024-08-15", + "value": 8.2 + }, + { + "date": "2025-02-05", + "value": 64.0 + }, + { + "date": "2025-02-18", + "value": 45.1 + }, + { + "date": "2025-08-10", + "value": 34.4 + }, + { + "date": "2025-08-20", + "value": 26.2 + }, + { + "date": "2025-09-06", + "value": 32.0 + }, + { + "date": "2025-09-12", + "value": 34.4 + }, + { + "date": "2025-09-18", + "value": 37.7 + }, + { + "date": "2025-10-04", + "value": 40.2 + }, + { + "date": "2025-10-10", + "value": 43.5 + }, + { + "date": "2025-10-16", + "value": 46.7 + }, + { + "date": "2025-11-05", + "value": 39.4 + }, + { + "date": "2025-11-11", + "value": 42.6 + }, + { + "date": "2025-11-17", + "value": 27.9 + }, + { + "date": "2025-12-06", + "value": 39.4 + }, + { + "date": "2025-12-12", + "value": 24.6 + }, + { + "date": "2025-12-18", + "value": 27.9 + }, + { + "date": "2026-01-04", + "value": 29.5 + }, + { + "date": "2026-01-10", + "value": 33.6 + }, + { + "date": "2026-01-16", + "value": 35.3 + }, + { + "date": "2026-02-05", + "value": 29.5 + }, + { + "date": "2026-02-11", + "value": 32.0 + }, + { + "date": "2026-02-17", + "value": 34.4 + }, + { + "date": "2026-03-06", + "value": 37.7 + }, + { + "date": "2026-03-12", + "value": 40.2 + }, + { + "date": "2026-03-18", + "value": 43.5 + }, + { + "date": "2026-04-04", + "value": 36.9 + }, + { + "date": "2026-04-10", + "value": 39.4 + }, + { + "date": "2026-04-16", + "value": 42.6 + }, + { + "date": "2026-05-05", + "value": 36.1 + }, + { + "date": "2026-05-11", + "value": 39.4 + }, + { + "date": "2026-05-17", + "value": 24.6 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 38.1, + "median": 38.1, + "p10": 26.0, + "p25": 30.6, + "p75": 45.8, + "p90": 50.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 53.3, + "median": 53.3, + "p10": 33.6, + "p25": 41.0, + "p75": 65.6, + "p90": 73.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 54.5, + "median": 54.5, + "p10": 47.0, + "p25": 49.9, + "p75": 59.3, + "p90": 62.1, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 30.3, + "median": 30.3, + "p10": 27.1, + "p25": 28.3, + "p75": 32.4, + "p90": 33.6, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 34.7, + "median": 34.4, + "p10": 32.5, + "p25": 33.2, + "p75": 36.1, + "p90": 37.1, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 43.5, + "median": 43.5, + "p10": 40.8, + "p25": 41.8, + "p75": 45.1, + "p90": 46.1, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 36.7, + "median": 39.4, + "p10": 30.2, + "p25": 33.6, + "p75": 41.0, + "p90": 42.0, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 30.6, + "median": 27.9, + "p10": 25.3, + "p25": 26.2, + "p75": 33.6, + "p90": 37.1, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 32.8, + "median": 33.6, + "p10": 30.3, + "p25": 31.6, + "p75": 34.4, + "p90": 34.9, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 32.0, + "median": 32.0, + "p10": 30.0, + "p25": 30.7, + "p75": 33.2, + "p90": 33.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 40.4, + "median": 40.2, + "p10": 38.2, + "p25": 38.9, + "p75": 41.8, + "p90": 42.8, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 39.6, + "median": 39.4, + "p10": 37.4, + "p25": 38.1, + "p75": 41.0, + "p90": 42.0, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 33.4, + "median": 36.1, + "p10": 26.9, + "p25": 30.3, + "p75": 37.7, + "p90": 38.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ], + "edges": [ + { + "source": "procurement_highland_arabica", + "target": "raw_dwell_highland_arabica", + "label": "101" + }, + { + "source": "procurement_lowland_robusta", + "target": "raw_dwell_lowland_robusta", + "label": "101" + }, + { + "source": "procurement_washed_bourbon", + "target": "raw_dwell_washed_bourbon", + "label": "101" + }, + { + "source": "raw_dwell_highland_arabica", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "raw_dwell_lowland_robusta", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "prod_duration_green_blend", + "target": "intermed_dwell_green_blend", + "label": "101" + }, + { + "source": "raw_dwell_washed_bourbon", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "intermed_dwell_green_blend", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "prod_duration_harbor_dark_roast", + "target": "prod_to_qa_pla", + "label": "101" + }, + { + "source": "post_qa_ship_pla", + "target": "direct_ship_pla", + "label": "601" + }, + { + "source": "post_qa_ship_pla", + "target": "transit_pla_hub1", + "label": "641" + }, + { + "source": "transit_pla_hub1", + "target": "dest_dwell_hub1" + }, + { + "source": "prod_to_qa_pla", + "target": "post_qa_ship_pla" + } + ], + "pipeline_summary": { + "direct": { + "label": "Direct to customer", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 29.9, + "median": 30, + "pct_of_total": 17.6, + "n": 60 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 99.8, + "median": 101, + "pct_of_total": 58.9, + "n": 60 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.6, + "median": 7, + "pct_of_total": 3.9, + "n": 60 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 33.2, + "median": 33, + "pct_of_total": 19.6, + "n": 60 + } + ], + "total_mean": 169.5, + "total_median": 171 + }, + "hub-1": { + "label": "HUB-1", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 28.4, + "median": 29, + "pct_of_total": 12.8, + "n": 40 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 102.1, + "median": 104, + "pct_of_total": 46.1, + "n": 40 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.2, + "median": 6, + "pct_of_total": 2.8, + "n": 40 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 84.8, + "median": 88, + "pct_of_total": 38.3, + "n": 40 + } + ], + "total_mean": 221.5, + "total_median": 227 + } + }, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica", + "step_ids": ["procurement_highland_arabica", "raw_dwell_highland_arabica"] + }, + { + "date": "2024-01-15", + "label": "QA process revision", + "step_ids": ["qa_hold_pla"] + } + ], + "batch_timelines": { + "batches": [ + { + "batch": "BATCH-007069", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-05-27", + "earliest_gr_date": "2024-05-29", + "earliest_production_start": "2024-07-03", + "fg_receipt_date": "2024-10-28", + "qa_release_date": "2024-11-03", + "ship_date": null, + "delivery_date": "2024-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 117, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 112, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 23 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-767678", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-13", + "earliest_gr_date": "2024-07-15", + "earliest_production_start": "2024-07-29", + "fg_receipt_date": "2024-11-05", + "qa_release_date": "2024-11-09", + "ship_date": null, + "delivery_date": "2024-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 99, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 36, + "total_days": 155, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 14, + "direct_ship_pla": 22 + } + }, + "total_from_po": 155 + }, + { + "batch": "BATCH-872783", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-25", + "earliest_gr_date": "2024-07-27", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-08", + "qa_release_date": "2024-11-15", + "ship_date": null, + "delivery_date": "2024-12-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 81, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 35, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 58, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 78, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 25 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-868247", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-20", + "earliest_gr_date": "2024-07-22", + "earliest_production_start": "2024-08-24", + "fg_receipt_date": "2024-11-10", + "qa_release_date": "2024-11-19", + "ship_date": null, + "delivery_date": "2024-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 37, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 61, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "direct_ship_pla": 20 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-775611", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-22", + "earliest_gr_date": "2024-07-24", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-22", + "qa_release_date": "2024-11-30", + "ship_date": null, + "delivery_date": "2024-12-31", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 95, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-544789", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-08", + "earliest_gr_date": "2024-07-10", + "earliest_production_start": "2024-08-05", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-12", + "ship_date": null, + "delivery_date": "2025-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 122, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 7, + "direct_ship_pla": 18 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-447665", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-14", + "earliest_gr_date": "2024-07-16", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-11", + "ship_date": null, + "delivery_date": "2025-01-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 31, + "total_days": 181, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "direct_ship_pla": 18 + } + }, + "total_from_po": 181 + }, + { + "batch": "BATCH-963613", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-26", + "fg_receipt_date": "2024-12-12", + "qa_release_date": "2024-12-19", + "ship_date": null, + "delivery_date": "2025-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 19 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-863299", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-05", + "earliest_gr_date": "2024-08-07", + "earliest_production_start": "2024-08-30", + "fg_receipt_date": "2024-12-21", + "qa_release_date": "2024-12-27", + "ship_date": null, + "delivery_date": "2025-01-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 26, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-528145", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-22", + "earliest_gr_date": "2024-08-24", + "earliest_production_start": "2024-09-11", + "fg_receipt_date": "2024-12-24", + "qa_release_date": "2024-12-30", + "ship_date": null, + "delivery_date": "2025-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 29, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 90, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 102, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 17 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-242499", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-17", + "earliest_gr_date": "2024-08-19", + "earliest_production_start": "2024-09-16", + "fg_receipt_date": "2024-12-26", + "qa_release_date": "2024-12-31", + "ship_date": null, + "delivery_date": "2025-02-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 33, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-576635", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-29", + "earliest_gr_date": "2024-10-01", + "earliest_production_start": "2024-10-26", + "fg_receipt_date": "2024-12-31", + "qa_release_date": "2025-01-07", + "ship_date": null, + "delivery_date": "2025-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 66, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 32, + "total_days": 132, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 47, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 64, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 24 + } + }, + "total_from_po": 132 + }, + { + "batch": "BATCH-221460", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-28", + "fg_receipt_date": "2025-01-01", + "qa_release_date": "2025-01-08", + "ship_date": null, + "delivery_date": "2025-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 126, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 36, + "total_days": 204, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 120, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 78, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 23 + } + }, + "total_from_po": 204 + }, + { + "batch": "BATCH-666578", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-06", + "fg_receipt_date": "2025-01-10", + "qa_release_date": "2025-01-18", + "ship_date": null, + "delivery_date": "2025-02-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-208118", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-19", + "fg_receipt_date": "2025-01-11", + "qa_release_date": "2025-01-19", + "ship_date": null, + "delivery_date": "2025-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 44, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 36, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 51, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 67, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 7, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 38, + "production_days": 7, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 15, + "direct_ship_pla": 21 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-458243", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-04", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-29", + "ship_date": null, + "delivery_date": "2025-03-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-207730", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-16", + "earliest_gr_date": "2024-09-18", + "earliest_production_start": "2024-10-14", + "fg_receipt_date": "2025-01-18", + "qa_release_date": "2025-01-22", + "ship_date": null, + "delivery_date": "2025-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 44, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 92, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 16, + "direct_ship_pla": 28 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-033995", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-27", + "earliest_gr_date": "2024-08-29", + "earliest_production_start": "2024-09-30", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-30", + "ship_date": null, + "delivery_date": "2025-03-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 114, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 18, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 17, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-559161", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-16", + "fg_receipt_date": "2025-02-14", + "qa_release_date": "2025-02-19", + "ship_date": null, + "delivery_date": "2025-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 27, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 10, + "direct_ship_pla": 17 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-043249", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-28", + "earliest_gr_date": "2024-09-30", + "earliest_production_start": "2024-10-27", + "fg_receipt_date": "2025-02-12", + "qa_release_date": "2025-02-15", + "ship_date": null, + "delivery_date": "2025-03-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 36, + "total_days": 176, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 12, + "direct_ship_pla": 24 + } + }, + "total_from_po": 176 + }, + { + "batch": "BATCH-876661", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-05", + "earliest_gr_date": "2024-10-07", + "earliest_production_start": "2024-11-06", + "fg_receipt_date": "2025-02-04", + "qa_release_date": "2025-02-11", + "ship_date": null, + "delivery_date": "2025-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 31 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-758211", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-24", + "earliest_gr_date": "2024-09-26", + "earliest_production_start": "2024-10-24", + "fg_receipt_date": "2025-02-22", + "qa_release_date": "2025-03-01", + "ship_date": null, + "delivery_date": "2025-04-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 191, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 191 + }, + { + "batch": "BATCH-198568", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-07", + "earliest_gr_date": "2024-10-09", + "earliest_production_start": "2024-10-29", + "fg_receipt_date": "2025-02-21", + "qa_release_date": "2025-03-02", + "ship_date": null, + "delivery_date": "2025-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 115, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 38, + "total_days": 184, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 13, + "direct_ship_pla": 25 + } + }, + "total_from_po": 184 + }, + { + "batch": "BATCH-499114", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-20", + "earliest_gr_date": "2024-11-22", + "earliest_production_start": "2024-12-17", + "fg_receipt_date": "2025-03-05", + "qa_release_date": "2025-03-14", + "ship_date": null, + "delivery_date": "2025-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 31, + "total_days": 145, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 33, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 145 + }, + { + "batch": "BATCH-947566", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-15", + "earliest_gr_date": "2024-10-17", + "earliest_production_start": "2024-11-17", + "fg_receipt_date": "2025-03-07", + "qa_release_date": "2025-03-10", + "ship_date": null, + "delivery_date": "2025-04-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 40, + "total_days": 186, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 14, + "direct_ship_pla": 26 + } + }, + "total_from_po": 186 + }, + { + "batch": "BATCH-154390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-25", + "earliest_gr_date": "2024-10-27", + "earliest_production_start": "2024-11-27", + "fg_receipt_date": "2025-03-10", + "qa_release_date": "2025-03-16", + "ship_date": null, + "delivery_date": "2025-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 40, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 22, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 22, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 44, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 28 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-557064", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-01", + "earliest_gr_date": "2024-12-03", + "earliest_production_start": "2025-01-02", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-05", + "ship_date": null, + "delivery_date": "2025-04-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 150, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 150 + }, + { + "batch": "BATCH-307333", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-17", + "earliest_gr_date": "2024-11-19", + "earliest_production_start": "2024-12-15", + "fg_receipt_date": "2025-03-27", + "qa_release_date": "2025-04-04", + "ship_date": null, + "delivery_date": "2025-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 32, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 73, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 16 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-891817", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-02", + "earliest_gr_date": "2024-12-04", + "earliest_production_start": "2024-12-16", + "fg_receipt_date": "2025-03-30", + "qa_release_date": "2025-04-07", + "ship_date": null, + "delivery_date": "2025-05-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 14, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 76, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 25 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-852390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-24", + "earliest_gr_date": "2024-11-26", + "earliest_production_start": "2024-12-29", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-06", + "ship_date": null, + "delivery_date": "2025-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 174, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 27 + } + }, + "total_from_po": 174 + }, + { + "batch": "BATCH-412722", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-31", + "earliest_gr_date": "2025-01-02", + "earliest_production_start": "2025-01-21", + "fg_receipt_date": "2025-04-15", + "qa_release_date": "2025-04-20", + "ship_date": null, + "delivery_date": "2025-05-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 21, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 32, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 9, + "direct_ship_pla": 23 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-357156", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-08", + "earliest_gr_date": "2024-11-10", + "earliest_production_start": "2024-12-13", + "fg_receipt_date": "2025-04-05", + "qa_release_date": "2025-04-13", + "ship_date": null, + "delivery_date": "2025-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 45, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 72, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 83, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 60, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 31 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-851698", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-04", + "earliest_gr_date": "2025-01-06", + "earliest_production_start": "2025-02-06", + "fg_receipt_date": "2025-04-22", + "qa_release_date": "2025-04-30", + "ship_date": null, + "delivery_date": "2025-06-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 75, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 33, + "total_days": 149, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 71, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 54, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 7, + "direct_ship_pla": 26 + } + }, + "total_from_po": 149 + }, + { + "batch": "BATCH-440021", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-29", + "earliest_gr_date": "2024-12-31", + "earliest_production_start": "2025-01-31", + "fg_receipt_date": "2025-05-05", + "qa_release_date": "2025-05-13", + "ship_date": null, + "delivery_date": "2025-06-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 26, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-546123", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-20", + "earliest_gr_date": "2024-12-22", + "earliest_production_start": "2025-01-18", + "fg_receipt_date": "2025-05-08", + "qa_release_date": "2025-05-15", + "ship_date": null, + "delivery_date": "2025-06-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-990560", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-29", + "earliest_gr_date": "2024-12-01", + "earliest_production_start": "2025-01-08", + "fg_receipt_date": "2025-05-16", + "qa_release_date": "2025-05-24", + "ship_date": null, + "delivery_date": "2025-06-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 40, + "seg_prodstart_to_prodfinish": 128, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 25, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 109, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 125, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-386297", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-03", + "earliest_gr_date": "2025-01-05", + "earliest_production_start": "2025-01-29", + "fg_receipt_date": "2025-05-19", + "qa_release_date": "2025-05-26", + "ship_date": null, + "delivery_date": "2025-06-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 50, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 14, + "direct_ship_pla": 15 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-947389", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-21", + "earliest_gr_date": "2025-01-23", + "earliest_production_start": "2025-02-19", + "fg_receipt_date": "2025-05-31", + "qa_release_date": "2025-06-06", + "ship_date": null, + "delivery_date": "2025-06-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 16, + "direct_ship_pla": 7 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-627234", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-26", + "earliest_gr_date": "2025-01-28", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-05-29", + "qa_release_date": "2025-06-01", + "ship_date": null, + "delivery_date": "2025-07-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 11, + "direct_ship_pla": 23 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-829707", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-14", + "earliest_gr_date": "2025-01-16", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-06-01", + "qa_release_date": "2025-06-09", + "ship_date": null, + "delivery_date": "2025-07-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 42, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-404324", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-22", + "earliest_gr_date": "2025-02-24", + "earliest_production_start": "2025-03-24", + "fg_receipt_date": "2025-06-18", + "qa_release_date": "2025-06-27", + "ship_date": null, + "delivery_date": "2025-07-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 19, + "total_days": 144, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 65, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 83, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 9, + "direct_ship_pla": 10 + } + }, + "total_from_po": 144 + }, + { + "batch": "BATCH-840018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-10", + "earliest_gr_date": "2025-02-12", + "earliest_production_start": "2025-03-15", + "fg_receipt_date": "2025-06-17", + "qa_release_date": "2025-06-21", + "ship_date": null, + "delivery_date": "2025-07-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 30, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 77, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 12, + "direct_ship_pla": 18 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-243511", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-11", + "earliest_gr_date": "2025-01-13", + "earliest_production_start": "2025-02-13", + "fg_receipt_date": "2025-06-13", + "qa_release_date": "2025-06-22", + "ship_date": null, + "delivery_date": "2025-07-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 35, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 116, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 53, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-394495", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-07", + "earliest_gr_date": "2025-02-09", + "earliest_production_start": "2025-03-14", + "fg_receipt_date": "2025-06-24", + "qa_release_date": "2025-07-02", + "ship_date": null, + "delivery_date": "2025-08-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 30, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 21 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-043032", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-15", + "earliest_gr_date": "2025-02-17", + "earliest_production_start": "2025-03-11", + "fg_receipt_date": "2025-06-29", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 33, + "total_days": 173, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 41, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 173 + }, + { + "batch": "BATCH-582158", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-26", + "earliest_gr_date": "2025-02-28", + "earliest_production_start": "2025-03-23", + "fg_receipt_date": "2025-06-28", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 38, + "total_days": 167, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 23 + } + }, + "total_from_po": 167 + }, + { + "batch": "BATCH-302264", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-30", + "earliest_gr_date": "2025-04-01", + "earliest_production_start": "2025-04-24", + "fg_receipt_date": "2025-07-16", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-08-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 24, + "total_days": 140, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 59, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 77, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 8 + } + }, + "total_from_po": 140 + }, + { + "batch": "BATCH-240076", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-14", + "qa_release_date": "2025-07-21", + "ship_date": null, + "delivery_date": "2025-08-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 151, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 151 + }, + { + "batch": "BATCH-804779", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-20", + "earliest_gr_date": "2025-02-22", + "earliest_production_start": "2025-03-22", + "fg_receipt_date": "2025-07-05", + "qa_release_date": "2025-07-12", + "ship_date": null, + "delivery_date": "2025-08-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 105, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 47, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 12, + "direct_ship_pla": 35 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-731192", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-15", + "earliest_gr_date": "2025-03-17", + "earliest_production_start": "2025-04-23", + "fg_receipt_date": "2025-07-22", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-09-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 39, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 38, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 27 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-482639", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-21", + "earliest_gr_date": "2025-02-23", + "earliest_production_start": "2025-03-30", + "fg_receipt_date": "2025-07-17", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-09-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 199, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "direct_ship_pla": 27 + } + }, + "total_from_po": 199 + }, + { + "batch": "BATCH-062870", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-01", + "earliest_gr_date": "2025-04-03", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-01", + "qa_release_date": "2025-08-07", + "ship_date": null, + "delivery_date": "2025-09-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 38, + "total_days": 166, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 87, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 26 + } + }, + "total_from_po": 166 + }, + { + "batch": "BATCH-231165", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-05", + "earliest_gr_date": "2025-05-07", + "earliest_production_start": "2025-06-09", + "fg_receipt_date": "2025-08-16", + "qa_release_date": "2025-08-22", + "ship_date": null, + "delivery_date": "2025-09-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 68, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 28, + "total_days": 137, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 43, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 14 + } + }, + "total_from_po": 137 + }, + { + "batch": "BATCH-213839", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-23", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-09-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 29, + "total_days": 164, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 47, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 164 + }, + { + "batch": "BATCH-750018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-11", + "earliest_gr_date": "2025-05-13", + "earliest_production_start": "2025-06-05", + "fg_receipt_date": "2025-08-31", + "qa_release_date": "2025-09-06", + "ship_date": null, + "delivery_date": "2025-09-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 87, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 24, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 6, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 6, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "direct_ship_pla": 17 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-880539", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-20", + "earliest_gr_date": "2025-04-22", + "earliest_production_start": "2025-05-26", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-10-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 85, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 41, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 68, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 28 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-155177", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-02", + "earliest_gr_date": "2025-05-04", + "earliest_production_start": "2025-06-18", + "fg_receipt_date": "2025-09-10", + "qa_release_date": "2025-09-16", + "ship_date": null, + "delivery_date": "2025-10-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 47, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 25, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-993261", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-29", + "earliest_gr_date": "2025-05-01", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-08-30", + "qa_release_date": "2025-09-04", + "ship_date": null, + "delivery_date": "2025-10-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 98, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 42, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 72, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 77, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 31 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-753433", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-27", + "earliest_gr_date": "2025-05-29", + "earliest_production_start": "2025-06-13", + "fg_receipt_date": "2025-09-23", + "qa_release_date": "2025-09-29", + "ship_date": null, + "delivery_date": "2025-10-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 8, + "direct_ship_pla": 15 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-476897", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-21", + "earliest_gr_date": "2025-04-23", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-09-14", + "qa_release_date": "2025-09-20", + "ship_date": null, + "delivery_date": "2025-10-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 25 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-521582", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-18", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-11-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 98, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 70, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 43, + "dest_dwell_hub1": 41 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-281803", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-07", + "fg_receipt_date": "2025-07-28", + "qa_release_date": "2025-08-01", + "ship_date": null, + "delivery_date": "2025-11-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 82, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 98, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-276962", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-05", + "earliest_gr_date": "2025-04-07", + "earliest_production_start": "2025-05-05", + "fg_receipt_date": "2025-08-17", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-11-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 79, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 101, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-217426", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-15", + "earliest_gr_date": "2025-04-17", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-08-24", + "qa_release_date": "2025-09-03", + "ship_date": null, + "delivery_date": "2025-11-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 10, + "seg_qa_to_customer": 76, + "total_days": 217, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 72, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 10, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 18, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 217 + }, + { + "batch": "BATCH-679445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-01", + "earliest_gr_date": "2025-05-03", + "earliest_production_start": "2025-06-03", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-11-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 77, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 62, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 36 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-584703", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-19", + "earliest_gr_date": "2025-04-21", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-09-06", + "qa_release_date": "2025-09-13", + "ship_date": null, + "delivery_date": "2025-11-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 77, + "total_days": 224, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 224 + }, + { + "batch": "BATCH-320907", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-03", + "earliest_gr_date": "2025-05-05", + "earliest_production_start": "2025-06-01", + "fg_receipt_date": "2025-08-12", + "qa_release_date": "2025-08-21", + "ship_date": null, + "delivery_date": "2025-12-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 72, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 106, + "total_days": 216, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 54, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 69, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 216 + }, + { + "batch": "BATCH-469894", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-09", + "earliest_gr_date": "2025-04-11", + "earliest_production_start": "2025-05-12", + "fg_receipt_date": "2025-08-29", + "qa_release_date": "2025-09-05", + "ship_date": null, + "delivery_date": "2025-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 96, + "total_days": 245, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 45, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 245 + }, + { + "batch": "BATCH-119167", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-10", + "earliest_gr_date": "2025-05-12", + "earliest_production_start": "2025-05-30", + "fg_receipt_date": "2025-09-19", + "qa_release_date": "2025-09-26", + "ship_date": null, + "delivery_date": "2025-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 80, + "total_days": 219, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 95, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 74, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 219 + }, + { + "batch": "BATCH-850977", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-17", + "earliest_gr_date": "2025-05-19", + "earliest_production_start": "2025-06-14", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-10-01", + "ship_date": null, + "delivery_date": "2025-12-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 81, + "total_days": 218, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 42, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 39 + } + }, + "total_from_po": 218 + }, + { + "batch": "BATCH-315004", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-21", + "earliest_gr_date": "2025-06-23", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-10-06", + "qa_release_date": "2025-10-14", + "ship_date": null, + "delivery_date": "2025-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 71, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 73, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 22, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-753733", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-04", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-09-28", + "ship_date": null, + "delivery_date": "2026-01-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 95, + "total_days": 211, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 80, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 52 + } + }, + "total_from_po": 211 + }, + { + "batch": "BATCH-006984", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-29", + "earliest_gr_date": "2025-05-31", + "earliest_production_start": "2025-06-15", + "fg_receipt_date": "2025-09-20", + "qa_release_date": "2025-09-27", + "ship_date": null, + "delivery_date": "2026-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 101, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 45, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 49 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-962763", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-06", + "fg_receipt_date": "2025-10-26", + "qa_release_date": "2025-11-02", + "ship_date": null, + "delivery_date": "2026-01-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 71, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 35 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-885445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-06-29", + "fg_receipt_date": "2025-10-03", + "qa_release_date": "2025-10-04", + "ship_date": null, + "delivery_date": "2026-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 1, + "seg_qa_to_customer": 105, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 1, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 63 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-622159", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-31", + "earliest_gr_date": "2025-06-02", + "earliest_production_start": "2025-06-26", + "fg_receipt_date": "2025-10-17", + "qa_release_date": "2025-10-23", + "ship_date": null, + "delivery_date": "2026-01-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 92, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-990714", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-03", + "earliest_gr_date": "2025-06-05", + "earliest_production_start": "2025-07-02", + "fg_receipt_date": "2025-10-14", + "qa_release_date": "2025-10-18", + "ship_date": null, + "delivery_date": "2026-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 102, + "total_days": 239, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 239 + }, + { + "batch": "BATCH-479016", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-14", + "earliest_gr_date": "2025-06-16", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-13", + "qa_release_date": "2025-11-19", + "ship_date": null, + "delivery_date": "2026-02-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 118, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 76, + "total_days": 234, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 96, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 114, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 34 + } + }, + "total_from_po": 234 + }, + { + "batch": "BATCH-080863", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-26", + "earliest_gr_date": "2025-06-28", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-12", + "ship_date": null, + "delivery_date": "2026-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 88, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-910231", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-05", + "earliest_gr_date": "2025-07-07", + "earliest_production_start": "2025-08-11", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-16", + "ship_date": null, + "delivery_date": "2026-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 84, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 75, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 86, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-997425", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-07", + "earliest_gr_date": "2025-08-09", + "earliest_production_start": "2025-09-06", + "fg_receipt_date": "2025-12-04", + "qa_release_date": "2025-12-12", + "ship_date": null, + "delivery_date": "2026-02-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 69, + "total_days": 196, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 24, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 37, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 30 + } + }, + "total_from_po": 196 + }, + { + "batch": "BATCH-618940", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-19", + "earliest_gr_date": "2025-06-21", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-11-29", + "qa_release_date": "2025-12-02", + "ship_date": null, + "delivery_date": "2026-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 125, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 84, + "total_days": 250, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 104, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 121, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 43, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 250 + }, + { + "batch": "BATCH-029240", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-14", + "earliest_gr_date": "2025-07-16", + "earliest_production_start": "2025-08-02", + "fg_receipt_date": "2025-11-19", + "qa_release_date": "2025-11-25", + "ship_date": null, + "delivery_date": "2026-03-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 231, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 77, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 44, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 231 + }, + { + "batch": "BATCH-013796", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-04", + "qa_release_date": "2026-01-13", + "ship_date": null, + "delivery_date": "2026-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 53, + "total_days": 202, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 27, + "dest_dwell_hub1": 15 + } + }, + "total_from_po": 202 + }, + { + "batch": "BATCH-563928", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-16", + "fg_receipt_date": "2025-12-08", + "qa_release_date": "2025-12-11", + "ship_date": null, + "delivery_date": "2026-03-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 92, + "total_days": 208, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 208 + }, + { + "batch": "BATCH-263609", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-12", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-10", + "ship_date": null, + "delivery_date": "2026-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 67, + "total_days": 215, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 20, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 15, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 215 + }, + { + "batch": "BATCH-786903", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-30", + "earliest_gr_date": "2025-09-01", + "earliest_production_start": "2025-09-23", + "fg_receipt_date": "2026-01-22", + "qa_release_date": "2026-01-28", + "ship_date": null, + "delivery_date": "2026-03-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 55, + "total_days": 206, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 103, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 17, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 17, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 206 + }, + { + "batch": "BATCH-676932", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-13", + "fg_receipt_date": "2025-12-19", + "qa_release_date": "2025-12-25", + "ship_date": null, + "delivery_date": "2026-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 94, + "total_days": 226, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 35, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 51, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 226 + }, + { + "batch": "BATCH-341567", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-10", + "earliest_gr_date": "2025-08-12", + "earliest_production_start": "2025-09-05", + "fg_receipt_date": "2025-12-27", + "qa_release_date": "2026-01-01", + "ship_date": null, + "delivery_date": "2026-04-04", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 93, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 23, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-162748", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-25", + "earliest_gr_date": "2025-08-27", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-09", + "ship_date": null, + "delivery_date": "2026-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 90, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 33, + "dest_dwell_hub1": 46 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-322485", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-08", + "earliest_gr_date": "2025-10-10", + "earliest_production_start": "2025-10-27", + "fg_receipt_date": "2026-02-01", + "qa_release_date": "2026-02-10", + "ship_date": null, + "delivery_date": "2026-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 63, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 36, + "dest_dwell_hub1": 16 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-780123", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-02", + "earliest_gr_date": "2025-09-04", + "earliest_production_start": "2025-10-02", + "fg_receipt_date": "2026-01-31", + "qa_release_date": "2026-02-08", + "ship_date": null, + "delivery_date": "2026-04-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 71, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 101, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-219665", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-06", + "earliest_gr_date": "2025-10-08", + "earliest_production_start": "2025-10-22", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 69, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 4, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-254225", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-08", + "earliest_gr_date": "2025-09-10", + "earliest_production_start": "2025-09-30", + "fg_receipt_date": "2026-01-28", + "qa_release_date": "2026-02-03", + "ship_date": null, + "delivery_date": "2026-05-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 87, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 115, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-311884", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-12", + "earliest_gr_date": "2025-09-14", + "earliest_production_start": "2025-10-10", + "fg_receipt_date": "2026-01-29", + "qa_release_date": "2026-02-04", + "ship_date": null, + "delivery_date": "2026-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 91, + "total_days": 236, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 236 + }, + { + "batch": "BATCH-534136", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-26", + "earliest_gr_date": "2025-09-28", + "earliest_production_start": "2025-11-08", + "fg_receipt_date": "2026-02-10", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 43, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 86, + "total_days": 228, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 40, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 228 + }, + { + "batch": "BATCH-718060", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-29", + "earliest_gr_date": "2025-10-01", + "earliest_production_start": "2025-11-09", + "fg_receipt_date": "2026-02-24", + "qa_release_date": "2026-02-28", + "ship_date": null, + "delivery_date": "2026-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 41, + "seg_prodstart_to_prodfinish": 107, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 78, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 103, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 14, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-802602", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-12", + "earliest_gr_date": "2025-10-14", + "earliest_production_start": "2025-11-04", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 51 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-136204", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-05", + "earliest_gr_date": "2025-10-07", + "earliest_production_start": "2025-11-05", + "fg_receipt_date": "2026-02-25", + "qa_release_date": "2026-03-03", + "ship_date": null, + "delivery_date": "2026-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 86, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 53, + "dest_dwell_hub1": 19 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-949254", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-14", + "earliest_gr_date": "2025-10-16", + "earliest_production_start": "2025-11-18", + "fg_receipt_date": "2026-02-19", + "qa_release_date": "2026-02-24", + "ship_date": null, + "delivery_date": "2026-06-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 93, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 99, + "total_days": 232, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 74, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 89, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 55 + } + }, + "total_from_po": 232 + } + ], + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.3, + "median": 30, + "p25": 25, + "p75": 34, + "n": 100 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 100.7, + "median": 102, + "p25": 90, + "p75": 112, + "n": 100 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.5, + "median": 7, + "p25": 6, + "p75": 8, + "n": 100 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 53.8, + "median": 40, + "p25": 31, + "p75": 81, + "n": 100 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 190.3, + "median": 188, + "p25": 167, + "p75": 222, + "n": 100 + } + }, + "per_route": { + "direct": { + "label": "Direct to customer", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.9, + "median": 30, + "p25": 26, + "p75": 35, + "n": 60 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 99.8, + "median": 101, + "p25": 90, + "p75": 110, + "n": 60 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.6, + "median": 7, + "p25": 6, + "p75": 8, + "n": 60 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 33.2, + "median": 33, + "p25": 29, + "p75": 38, + "n": 60 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 169.5, + "median": 170, + "p25": 159, + "p75": 182, + "n": 60 + } + } + }, + "hub-1": { + "label": "HUB-1", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 28.4, + "median": 29, + "p25": 24, + "p75": 33, + "n": 40 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 102.1, + "median": 104, + "p25": 96, + "p75": 113, + "n": 40 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.2, + "median": 6, + "p25": 5, + "p75": 8, + "n": 40 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 84.8, + "median": 88, + "p25": 76, + "p75": 96, + "n": 40 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 221.6, + "median": 223, + "p25": 215, + "p75": 232, + "n": 40 + } + } + } + }, + "coverage": { + "traced": 100, + "total": 100 + } + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/dest_dwell_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/dest_dwell_hub1.json new file mode 100644 index 00000000000..c70a1fc781e --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/dest_dwell_hub1.json @@ -0,0 +1,432 @@ +{ + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "durations": [ + 34.4, 53.3, 23.0, 77.9, 28.7, 8.2, 64.0, 45.1, 34.4, 26.2, 32.0, 34.4, 37.7, + 40.2, 43.5, 46.7, 39.4, 42.6, 27.9, 39.4, 24.6, 27.9, 29.5, 33.6, 35.3, + 29.5, 32.0, 34.4, 37.7, 40.2, 43.5, 36.9, 39.4, 42.6, 36.1, 39.4, 24.6 + ], + "observations": [ + { + "date": "2022-09-15", + "value": 34.4 + }, + { + "date": "2023-05-05", + "value": 53.3 + }, + { + "date": "2023-05-20", + "value": 23.0 + }, + { + "date": "2024-01-10", + "value": 77.9 + }, + { + "date": "2024-01-25", + "value": 28.7 + }, + { + "date": "2024-08-15", + "value": 8.2 + }, + { + "date": "2025-02-05", + "value": 64.0 + }, + { + "date": "2025-02-18", + "value": 45.1 + }, + { + "date": "2025-08-10", + "value": 34.4 + }, + { + "date": "2025-08-20", + "value": 26.2 + }, + { + "date": "2025-09-06", + "value": 32.0 + }, + { + "date": "2025-09-12", + "value": 34.4 + }, + { + "date": "2025-09-18", + "value": 37.7 + }, + { + "date": "2025-10-04", + "value": 40.2 + }, + { + "date": "2025-10-10", + "value": 43.5 + }, + { + "date": "2025-10-16", + "value": 46.7 + }, + { + "date": "2025-11-05", + "value": 39.4 + }, + { + "date": "2025-11-11", + "value": 42.6 + }, + { + "date": "2025-11-17", + "value": 27.9 + }, + { + "date": "2025-12-06", + "value": 39.4 + }, + { + "date": "2025-12-12", + "value": 24.6 + }, + { + "date": "2025-12-18", + "value": 27.9 + }, + { + "date": "2026-01-04", + "value": 29.5 + }, + { + "date": "2026-01-10", + "value": 33.6 + }, + { + "date": "2026-01-16", + "value": 35.3 + }, + { + "date": "2026-02-05", + "value": 29.5 + }, + { + "date": "2026-02-11", + "value": 32.0 + }, + { + "date": "2026-02-17", + "value": 34.4 + }, + { + "date": "2026-03-06", + "value": 37.7 + }, + { + "date": "2026-03-12", + "value": 40.2 + }, + { + "date": "2026-03-18", + "value": 43.5 + }, + { + "date": "2026-04-04", + "value": 36.9 + }, + { + "date": "2026-04-10", + "value": 39.4 + }, + { + "date": "2026-04-16", + "value": 42.6 + }, + { + "date": "2026-05-05", + "value": 36.1 + }, + { + "date": "2026-05-11", + "value": 39.4 + }, + { + "date": "2026-05-17", + "value": 24.6 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 38.1, + "median": 38.1, + "p10": 26.0, + "p25": 30.6, + "p75": 45.8, + "p90": 50.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 53.3, + "median": 53.3, + "p10": 33.6, + "p25": 41.0, + "p75": 65.6, + "p90": 73.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 54.5, + "median": 54.5, + "p10": 47.0, + "p25": 49.9, + "p75": 59.3, + "p90": 62.1, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 30.3, + "median": 30.3, + "p10": 27.1, + "p25": 28.3, + "p75": 32.4, + "p90": 33.6, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 34.7, + "median": 34.4, + "p10": 32.5, + "p25": 33.2, + "p75": 36.1, + "p90": 37.1, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 43.5, + "median": 43.5, + "p10": 40.8, + "p25": 41.8, + "p75": 45.1, + "p90": 46.1, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 36.7, + "median": 39.4, + "p10": 30.2, + "p25": 33.6, + "p75": 41.0, + "p90": 42.0, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 30.6, + "median": 27.9, + "p10": 25.3, + "p25": 26.2, + "p75": 33.6, + "p90": 37.1, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 32.8, + "median": 33.6, + "p10": 30.3, + "p25": 31.6, + "p75": 34.4, + "p90": 34.9, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 32.0, + "median": 32.0, + "p10": 30.0, + "p25": 30.7, + "p75": 33.2, + "p90": 33.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 40.4, + "median": 40.2, + "p10": 38.2, + "p25": 38.9, + "p75": 41.8, + "p90": 42.8, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 39.6, + "median": 39.4, + "p10": 37.4, + "p25": 38.1, + "p75": 41.0, + "p90": 42.0, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 33.4, + "median": 36.1, + "p10": 26.9, + "p25": 30.3, + "p75": 37.7, + "p90": 38.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "stats": { + "n": 37, + "mean": 36.9, + "median": 36.1, + "std": 14.0, + "min": 8.2, + "max": 77.9, + "p25": 29.5, + "p75": 40.2, + "p85": 43.5, + "p95": 53.3 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 23.37, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/intermed_dwell_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/intermed_dwell_green_blend.json new file mode 100644 index 00000000000..89055ec6a18 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/intermed_dwell_green_blend.json @@ -0,0 +1,595 @@ +{ + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "durations": [ + 9.8, 20.5, 6.6, 28.7, 12.3, 4.1, 18.0, 14.8, 32.8, 8.2, 45.1, 1.6, 23.0, + 12.3, 6.6, 16.4, 36.9, 9.8, 2.5, 14.8, 24.6, 6.6, 18.0, 28.7, 4.1, 12.3, + 34.4, 8.2, 11.5, 13.1, 13.9, 14.8, 15.6, 11.5, 12.3, 13.1, 14.8, 9.0, 14.8, + 15.6, 16.4, 11.5, 12.3, 13.9, 15.6, 9.8, 11.5, 12.3, 13.9, 9.0, 9.8, 10.7, + 11.5, 10.7, 11.5, 13.1, 13.9, 14.8, 10.7, 11.5, 12.3, 13.1, 14.8, 13.1, + 14.8, 15.6, 16.4, 11.5, 13.1, 13.9, 15.6, 9.8, 11.5 + ], + "observations": [ + { + "date": "2022-05-05", + "value": 9.8 + }, + { + "date": "2022-05-15", + "value": 20.5 + }, + { + "date": "2022-05-22", + "value": 6.6 + }, + { + "date": "2022-11-03", + "value": 28.7 + }, + { + "date": "2022-11-10", + "value": 12.3 + }, + { + "date": "2022-11-18", + "value": 4.1 + }, + { + "date": "2022-11-25", + "value": 18.0 + }, + { + "date": "2023-05-08", + "value": 14.8 + }, + { + "date": "2023-05-15", + "value": 32.8 + }, + { + "date": "2023-05-22", + "value": 8.2 + }, + { + "date": "2023-11-06", + "value": 45.1 + }, + { + "date": "2023-11-13", + "value": 1.6 + }, + { + "date": "2023-11-20", + "value": 23.0 + }, + { + "date": "2023-11-27", + "value": 12.3 + }, + { + "date": "2023-11-30", + "value": 6.6 + }, + { + "date": "2024-05-06", + "value": 16.4 + }, + { + "date": "2024-05-13", + "value": 36.9 + }, + { + "date": "2024-05-20", + "value": 9.8 + }, + { + "date": "2024-05-27", + "value": 2.5 + }, + { + "date": "2024-11-04", + "value": 14.8 + }, + { + "date": "2024-11-11", + "value": 24.6 + }, + { + "date": "2024-11-18", + "value": 6.6 + }, + { + "date": "2025-05-05", + "value": 18.0 + }, + { + "date": "2025-05-09", + "value": 28.7 + }, + { + "date": "2025-05-13", + "value": 4.1 + }, + { + "date": "2025-05-17", + "value": 12.3 + }, + { + "date": "2025-05-21", + "value": 34.4 + }, + { + "date": "2025-05-25", + "value": 8.2 + }, + { + "date": "2025-09-05", + "value": 11.5 + }, + { + "date": "2025-09-11", + "value": 13.1 + }, + { + "date": "2025-09-17", + "value": 13.9 + }, + { + "date": "2025-09-23", + "value": 14.8 + }, + { + "date": "2025-09-29", + "value": 15.6 + }, + { + "date": "2025-10-06", + "value": 11.5 + }, + { + "date": "2025-10-12", + "value": 12.3 + }, + { + "date": "2025-10-18", + "value": 13.1 + }, + { + "date": "2025-10-24", + "value": 14.8 + }, + { + "date": "2025-10-30", + "value": 9.0 + }, + { + "date": "2025-11-04", + "value": 14.8 + }, + { + "date": "2025-11-10", + "value": 15.6 + }, + { + "date": "2025-11-16", + "value": 16.4 + }, + { + "date": "2025-11-22", + "value": 11.5 + }, + { + "date": "2025-11-28", + "value": 12.3 + }, + { + "date": "2025-12-05", + "value": 13.9 + }, + { + "date": "2025-12-11", + "value": 15.6 + }, + { + "date": "2025-12-17", + "value": 9.8 + }, + { + "date": "2025-12-23", + "value": 11.5 + }, + { + "date": "2025-12-29", + "value": 12.3 + }, + { + "date": "2026-01-06", + "value": 13.9 + }, + { + "date": "2026-01-12", + "value": 9.0 + }, + { + "date": "2026-01-18", + "value": 9.8 + }, + { + "date": "2026-01-24", + "value": 10.7 + }, + { + "date": "2026-01-30", + "value": 11.5 + }, + { + "date": "2026-02-04", + "value": 10.7 + }, + { + "date": "2026-02-10", + "value": 11.5 + }, + { + "date": "2026-02-16", + "value": 13.1 + }, + { + "date": "2026-02-22", + "value": 13.9 + }, + { + "date": "2026-02-28", + "value": 14.8 + }, + { + "date": "2026-03-05", + "value": 10.7 + }, + { + "date": "2026-03-11", + "value": 11.5 + }, + { + "date": "2026-03-17", + "value": 12.3 + }, + { + "date": "2026-03-23", + "value": 13.1 + }, + { + "date": "2026-03-29", + "value": 14.8 + }, + { + "date": "2026-04-06", + "value": 13.1 + }, + { + "date": "2026-04-12", + "value": 14.8 + }, + { + "date": "2026-04-18", + "value": 15.6 + }, + { + "date": "2026-04-24", + "value": 16.4 + }, + { + "date": "2026-04-30", + "value": 11.5 + }, + { + "date": "2026-05-04", + "value": 13.1 + }, + { + "date": "2026-05-10", + "value": 13.9 + }, + { + "date": "2026-05-16", + "value": 15.6 + }, + { + "date": "2026-05-22", + "value": 9.8 + }, + { + "date": "2026-05-28", + "value": 11.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 12.3, + "median": 9.8, + "p10": 7.2, + "p25": 8.2, + "p75": 15.2, + "p90": 18.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 15.8, + "median": 15.2, + "p10": 6.6, + "p25": 10.2, + "p75": 20.7, + "p90": 25.5, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 18.6, + "median": 14.8, + "p10": 9.5, + "p25": 11.5, + "p75": 23.8, + "p90": 29.2, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 17.7, + "median": 12.3, + "p10": 3.6, + "p25": 6.6, + "p75": 23.0, + "p90": 36.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 16.4, + "median": 13.1, + "p10": 4.7, + "p25": 8.0, + "p75": 21.6, + "p90": 30.7, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 15.3, + "median": 14.8, + "p10": 8.2, + "p25": 10.7, + "p75": 19.7, + "p90": 22.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 17.6, + "median": 15.2, + "p10": 6.1, + "p25": 9.3, + "p75": 26.1, + "p90": 31.6, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 13.8, + "median": 13.9, + "p10": 12.1, + "p25": 13.1, + "p75": 14.8, + "p90": 15.3, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 12.1, + "median": 12.3, + "p10": 10.0, + "p25": 11.5, + "p75": 13.1, + "p90": 14.1, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 14.1, + "median": 14.8, + "p10": 11.8, + "p25": 12.3, + "p75": 15.6, + "p90": 16.1, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 12.6, + "median": 12.3, + "p10": 10.5, + "p25": 11.5, + "p75": 13.9, + "p90": 14.9, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 11.0, + "median": 10.7, + "p10": 9.3, + "p25": 9.8, + "p75": 11.5, + "p90": 13.0, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 12.8, + "median": 13.1, + "p10": 11.0, + "p25": 11.5, + "p75": 13.9, + "p90": 14.4, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 12.5, + "median": 12.3, + "p10": 11.0, + "p25": 11.5, + "p75": 13.1, + "p90": 14.1, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 14.3, + "median": 14.8, + "p10": 12.1, + "p25": 13.1, + "p75": 15.6, + "p90": 16.1, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 12.8, + "median": 13.1, + "p10": 10.5, + "p25": 11.5, + "p75": 13.9, + "p90": 14.9, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "stats": { + "n": 73, + "mean": 14.3, + "median": 13.1, + "std": 9.0, + "min": 1.6, + "max": 45.1, + "p25": 10.7, + "p75": 15.6, + "p85": 16.4, + "p95": 28.7 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "annotations": [], + "cost": { + "unit_price": 10.25, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 28, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/post_qa_ship_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/post_qa_ship_pla.json new file mode 100644 index 00000000000..dcb5e8aef54 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/post_qa_ship_pla.json @@ -0,0 +1,514 @@ +{ + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "durations": [ + 6.6, 18.0, 34.4, 4.9, 14.8, 23.0, 9.8, 1.6, 12.3, 4.1, 16.4, 3.3, 11.5, + 12.3, 8.2, 9.0, 9.8, 11.5, 6.6, 8.2, 9.0, 9.0, 8.2, 9.8, 9.8, 10.7, 11.5, + 8.2, 9.0, 9.8, 10.7, 11.5, 10.7, 11.5, 12.3, 13.1, 9.0, 10.7, 11.5, 12.3, + 8.2, 9.0, 10.7, 11.5, 6.6, 8.2, 9.0, 13.1, 8.2, 9.8, 9.8, 10.7, 7.4, 8.2, + 9.0, 9.8, 10.7 + ], + "observations": [ + { + "date": "2023-03-10", + "value": 6.6 + }, + { + "date": "2023-03-25", + "value": 18.0 + }, + { + "date": "2023-09-20", + "value": 34.4 + }, + { + "date": "2024-03-15", + "value": 4.9 + }, + { + "date": "2024-03-28", + "value": 14.8 + }, + { + "date": "2024-09-05", + "value": 23.0 + }, + { + "date": "2024-09-15", + "value": 9.8 + }, + { + "date": "2024-09-25", + "value": 1.6 + }, + { + "date": "2025-03-10", + "value": 12.3 + }, + { + "date": "2025-03-22", + "value": 4.1 + }, + { + "date": "2025-07-08", + "value": 16.4 + }, + { + "date": "2025-07-22", + "value": 3.3 + }, + { + "date": "2025-09-05", + "value": 11.5 + }, + { + "date": "2025-09-11", + "value": 12.3 + }, + { + "date": "2025-09-17", + "value": 8.2 + }, + { + "date": "2025-09-23", + "value": 9.0 + }, + { + "date": "2025-09-29", + "value": 9.8 + }, + { + "date": "2025-10-06", + "value": 11.5 + }, + { + "date": "2025-10-12", + "value": 6.6 + }, + { + "date": "2025-10-18", + "value": 8.2 + }, + { + "date": "2025-10-24", + "value": 9.0 + }, + { + "date": "2025-10-30", + "value": 9.0 + }, + { + "date": "2025-11-04", + "value": 8.2 + }, + { + "date": "2025-11-10", + "value": 9.8 + }, + { + "date": "2025-11-16", + "value": 9.8 + }, + { + "date": "2025-11-22", + "value": 10.7 + }, + { + "date": "2025-11-28", + "value": 11.5 + }, + { + "date": "2025-12-05", + "value": 8.2 + }, + { + "date": "2025-12-11", + "value": 9.0 + }, + { + "date": "2025-12-17", + "value": 9.8 + }, + { + "date": "2025-12-23", + "value": 10.7 + }, + { + "date": "2025-12-29", + "value": 11.5 + }, + { + "date": "2026-01-06", + "value": 10.7 + }, + { + "date": "2026-01-12", + "value": 11.5 + }, + { + "date": "2026-01-18", + "value": 12.3 + }, + { + "date": "2026-01-24", + "value": 13.1 + }, + { + "date": "2026-01-30", + "value": 9.0 + }, + { + "date": "2026-02-04", + "value": 10.7 + }, + { + "date": "2026-02-10", + "value": 11.5 + }, + { + "date": "2026-02-16", + "value": 12.3 + }, + { + "date": "2026-02-22", + "value": 8.2 + }, + { + "date": "2026-02-28", + "value": 9.0 + }, + { + "date": "2026-03-05", + "value": 10.7 + }, + { + "date": "2026-03-11", + "value": 11.5 + }, + { + "date": "2026-03-17", + "value": 6.6 + }, + { + "date": "2026-03-23", + "value": 8.2 + }, + { + "date": "2026-03-29", + "value": 9.0 + }, + { + "date": "2026-04-06", + "value": 13.1 + }, + { + "date": "2026-04-12", + "value": 8.2 + }, + { + "date": "2026-04-18", + "value": 9.8 + }, + { + "date": "2026-04-24", + "value": 9.8 + }, + { + "date": "2026-04-30", + "value": 10.7 + }, + { + "date": "2026-05-04", + "value": 7.4 + }, + { + "date": "2026-05-10", + "value": 8.2 + }, + { + "date": "2026-05-16", + "value": 9.0 + }, + { + "date": "2026-05-22", + "value": 9.8 + }, + { + "date": "2026-05-28", + "value": 10.7 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 12.3, + "median": 12.3, + "p10": 7.7, + "p25": 9.4, + "p75": 15.2, + "p90": 16.9, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 9.8, + "median": 9.8, + "p10": 5.9, + "p25": 7.4, + "p75": 12.3, + "p90": 13.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 11.5, + "median": 9.8, + "p10": 3.3, + "p25": 5.7, + "p75": 16.4, + "p90": 20.3, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 8.2, + "median": 8.2, + "p10": 4.9, + "p25": 6.1, + "p75": 10.2, + "p90": 11.5, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 9.8, + "median": 9.8, + "p10": 4.6, + "p25": 6.6, + "p75": 13.1, + "p90": 15.1, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 10.2, + "median": 9.8, + "p10": 8.5, + "p25": 9.0, + "p75": 11.5, + "p90": 12.0, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 8.9, + "median": 9.0, + "p10": 7.2, + "p25": 8.2, + "p75": 9.0, + "p90": 10.5, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 10.0, + "median": 9.8, + "p10": 8.9, + "p25": 9.8, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 9.8, + "median": 9.8, + "p10": 8.5, + "p25": 9.0, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 11.3, + "median": 11.5, + "p10": 9.7, + "p25": 10.7, + "p75": 12.3, + "p90": 12.8, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 10.3, + "median": 10.7, + "p10": 8.5, + "p25": 9.0, + "p75": 11.5, + "p90": 12.0, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 9.2, + "median": 9.0, + "p10": 7.2, + "p25": 8.2, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 10.3, + "median": 9.8, + "p10": 8.9, + "p25": 9.8, + "p75": 10.7, + "p90": 12.1, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 9.0, + "median": 9.0, + "p10": 7.7, + "p25": 8.2, + "p75": 9.8, + "p90": 10.3, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "stats": { + "n": 57, + "mean": 10.4, + "median": 9.8, + "std": 5.6, + "min": 1.6, + "max": 34.4, + "p25": 8.2, + "p75": 11.5, + "p85": 12.3, + "p95": 16.4 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 23.37, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 12, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_highland_arabica.json new file mode 100644 index 00000000000..c01b86d211f --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_highland_arabica.json @@ -0,0 +1,3304 @@ +{ + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "durations": [ + 45.1, 34.4, 6.6, 51.7, 31.2, 18.0, 58.2, 24.6, 36.9, 14.8, 86.1, 28.7, 9.8, + 39.4, 32.0, 33.6, 36.1, 39.4, 41.8, 30.3, 32.8, 36.1, 38.5, 25.4, 29.5, + 32.8, 35.3, 22.1, 25.4, 37.7, 40.2, 27.1, 30.3, 32.0, 36.9, 23.8, 27.1, + 28.7, 31.2, 28.7, 32.0, 33.6, 36.1, 39.4, 28.7, 30.3, 32.8, 36.1, 38.5, + 27.1, 29.5, 32.8, 35.3, 22.1, 34.4, 37.7, 40.2, 27.1, 30.3 + ], + "observations": [ + { + "date": "2022-03-15", + "value": 45.1 + }, + { + "date": "2022-06-10", + "value": 34.4 + }, + { + "date": "2022-09-22", + "value": 6.6 + }, + { + "date": "2022-12-05", + "value": 51.7 + }, + { + "date": "2023-02-14", + "value": 31.2 + }, + { + "date": "2023-05-30", + "value": 18.0 + }, + { + "date": "2023-08-17", + "value": 58.2 + }, + { + "date": "2023-11-02", + "value": 24.6 + }, + { + "date": "2024-01-25", + "value": 36.9 + }, + { + "date": "2024-04-11", + "value": 14.8 + }, + { + "date": "2024-07-09", + "value": 86.1 + }, + { + "date": "2024-10-03", + "value": 28.7 + }, + { + "date": "2025-01-20", + "value": 9.8 + }, + { + "date": "2025-04-08", + "value": 39.4 + }, + { + "date": "2025-09-05", + "value": 32.0 + }, + { + "date": "2025-09-11", + "value": 33.6 + }, + { + "date": "2025-09-17", + "value": 36.1 + }, + { + "date": "2025-09-23", + "value": 39.4 + }, + { + "date": "2025-09-29", + "value": 41.8 + }, + { + "date": "2025-10-06", + "value": 30.3 + }, + { + "date": "2025-10-12", + "value": 32.8 + }, + { + "date": "2025-10-18", + "value": 36.1 + }, + { + "date": "2025-10-24", + "value": 38.5 + }, + { + "date": "2025-10-30", + "value": 25.4 + }, + { + "date": "2025-11-04", + "value": 29.5 + }, + { + "date": "2025-11-10", + "value": 32.8 + }, + { + "date": "2025-11-16", + "value": 35.3 + }, + { + "date": "2025-11-22", + "value": 22.1 + }, + { + "date": "2025-11-28", + "value": 25.4 + }, + { + "date": "2025-12-05", + "value": 37.7 + }, + { + "date": "2025-12-11", + "value": 40.2 + }, + { + "date": "2025-12-17", + "value": 27.1 + }, + { + "date": "2025-12-23", + "value": 30.3 + }, + { + "date": "2025-12-29", + "value": 32.0 + }, + { + "date": "2026-01-06", + "value": 36.9 + }, + { + "date": "2026-01-12", + "value": 23.8 + }, + { + "date": "2026-01-18", + "value": 27.1 + }, + { + "date": "2026-01-24", + "value": 28.7 + }, + { + "date": "2026-01-30", + "value": 31.2 + }, + { + "date": "2026-02-04", + "value": 28.7 + }, + { + "date": "2026-02-10", + "value": 32.0 + }, + { + "date": "2026-02-16", + "value": 33.6 + }, + { + "date": "2026-02-22", + "value": 36.1 + }, + { + "date": "2026-02-28", + "value": 39.4 + }, + { + "date": "2026-03-05", + "value": 28.7 + }, + { + "date": "2026-03-11", + "value": 30.3 + }, + { + "date": "2026-03-17", + "value": 32.8 + }, + { + "date": "2026-03-23", + "value": 36.1 + }, + { + "date": "2026-03-29", + "value": 38.5 + }, + { + "date": "2026-04-06", + "value": 27.1 + }, + { + "date": "2026-04-12", + "value": 29.5 + }, + { + "date": "2026-04-18", + "value": 32.8 + }, + { + "date": "2026-04-24", + "value": 35.3 + }, + { + "date": "2026-04-30", + "value": 22.1 + }, + { + "date": "2026-05-04", + "value": 34.4 + }, + { + "date": "2026-05-10", + "value": 37.7 + }, + { + "date": "2026-05-16", + "value": 40.2 + }, + { + "date": "2026-05-22", + "value": 27.1 + }, + { + "date": "2026-05-28", + "value": 30.3 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2022-06", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1 + }, + { + "month": "2022-09", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2022-12", + "mean": 51.7, + "median": 51.7, + "p10": 51.7, + "p25": 51.7, + "p75": 51.7, + "p90": 51.7, + "n": 1 + }, + { + "month": "2023-02", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2023-05", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 58.2, + "median": 58.2, + "p10": 58.2, + "p25": 58.2, + "p75": 58.2, + "p90": 58.2, + "n": 1 + }, + { + "month": "2023-11", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2024-01", + "mean": 36.9, + "median": 36.9, + "p10": 36.9, + "p25": 36.9, + "p75": 36.9, + "p90": 36.9, + "n": 1 + }, + { + "month": "2024-04", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2024-07", + "mean": 86.1, + "median": 86.1, + "p10": 86.1, + "p25": 86.1, + "p75": 86.1, + "p90": 86.1, + "n": 1 + }, + { + "month": "2024-10", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2025-04", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2025-09", + "mean": 36.6, + "median": 36.1, + "p10": 32.6, + "p25": 33.6, + "p75": 39.4, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 32.6, + "median": 32.8, + "p10": 27.4, + "p25": 30.3, + "p75": 36.1, + "p90": 37.6, + "n": 5 + }, + { + "month": "2025-11", + "mean": 29.0, + "median": 29.5, + "p10": 23.5, + "p25": 25.4, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2025-12", + "mean": 33.5, + "median": 32.0, + "p10": 28.4, + "p25": 30.3, + "p75": 37.7, + "p90": 39.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 29.5, + "median": 28.7, + "p10": 25.1, + "p25": 27.1, + "p75": 31.2, + "p90": 34.6, + "n": 5 + }, + { + "month": "2026-02", + "mean": 33.9, + "median": 33.6, + "p10": 30.0, + "p25": 32.0, + "p75": 36.1, + "p90": 38.0, + "n": 5 + }, + { + "month": "2026-03", + "mean": 33.3, + "median": 32.8, + "p10": 29.4, + "p25": 30.3, + "p75": 36.1, + "p90": 37.6, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.4, + "median": 29.5, + "p10": 24.1, + "p25": 27.1, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 33.9, + "median": 34.4, + "p10": 28.4, + "p25": 30.3, + "p75": 37.7, + "p90": 39.2, + "n": 5 + } + ], + "stats": { + "n": 59, + "mean": 33.0, + "median": 32.8, + "std": 13.3, + "min": 6.6, + "max": 86.1, + "p25": 28.7, + "p75": 36.9, + "p85": 39.4, + "p95": 45.1 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_highland_arabica", + "po_number": "4500000003", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000003", + "first_gr_date": "2025-06-03", + "days_vs_promised": -2, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000000", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000000", + "first_gr_date": "2025-06-06", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000005", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000005", + "first_gr_date": "2025-06-13", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000001", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000001", + "first_gr_date": "2025-06-15", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000002", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000002", + "first_gr_date": "2025-06-20", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000004", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000004", + "first_gr_date": "2025-06-21", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000006", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000006", + "first_gr_date": "2025-07-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000007", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000007", + "first_gr_date": "2025-07-10", + "days_vs_promised": 4, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000009", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000009", + "first_gr_date": "2025-07-21", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000010", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000010", + "first_gr_date": "2025-07-26", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000008", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000008", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000012", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000012", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000013", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000013", + "first_gr_date": "2025-08-20", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000014", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000014", + "first_gr_date": "2025-08-23", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000011", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000011", + "first_gr_date": "2025-08-25", + "days_vs_promised": 6, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000015", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000015", + "first_gr_date": "2025-08-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000016", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000016", + "first_gr_date": "2025-09-25", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000019", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000019", + "first_gr_date": "2025-09-27", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000020", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000020", + "first_gr_date": "2025-10-03", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000017", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000017", + "first_gr_date": "2025-10-05", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000018", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000018", + "first_gr_date": "2025-10-10", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000022", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000022", + "first_gr_date": "2025-10-16", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000021", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000021", + "first_gr_date": "2025-10-19", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000023", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000023", + "first_gr_date": "2025-10-31", + "days_vs_promised": 2, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000024", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000024", + "first_gr_date": "2025-11-01", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000025", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000025", + "first_gr_date": "2025-11-17", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000027", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000027", + "first_gr_date": "2025-11-29", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000028", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000028", + "first_gr_date": "2025-12-03", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000026", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000026", + "first_gr_date": "2025-12-04", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000029", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000029", + "first_gr_date": "2025-12-19", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000030", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000030", + "first_gr_date": "2025-12-24", + "days_vs_promised": 1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000034", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000034", + "first_gr_date": "2026-01-11", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000031", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000031", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000033", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000033", + "first_gr_date": "2026-01-13", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000035", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000035", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000032", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000032", + "first_gr_date": "2026-01-17", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000036", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000036", + "first_gr_date": "2026-01-31", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000037", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000037", + "first_gr_date": "2026-02-08", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000038", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000038", + "first_gr_date": "2026-02-11", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000040", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000040", + "first_gr_date": "2026-02-25", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000039", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000039", + "first_gr_date": "2026-03-01", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000041", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000041", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000042", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000042", + "first_gr_date": "2026-03-18", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000043", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000043", + "first_gr_date": "2026-03-22", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000044", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000044", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000045", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000045", + "first_gr_date": "2026-03-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000057", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000057", + "first_gr_date": "2026-04-01", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000068", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000068", + "first_gr_date": "2026-04-07", + "days_vs_promised": 4, + "lead_time_days": 42 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000069", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000069", + "first_gr_date": "2026-04-09", + "days_vs_promised": 3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000056", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000056", + "first_gr_date": "2026-04-10", + "days_vs_promised": 1, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000058", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000058", + "first_gr_date": "2026-04-12", + "days_vs_promised": 5, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000071", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000071", + "first_gr_date": "2026-04-13", + "days_vs_promised": -3, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000060", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000060", + "first_gr_date": "2026-04-14", + "days_vs_promised": 1, + "lead_time_days": 21 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000048", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000048", + "first_gr_date": "2026-04-22", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000050", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000050", + "first_gr_date": "2026-04-27", + "days_vs_promised": -3, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000046", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000046", + "first_gr_date": "2026-04-29", + "days_vs_promised": 3, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000047", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000047", + "first_gr_date": "2026-05-01", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000059", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000059", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000049", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000049", + "first_gr_date": "2026-05-06", + "days_vs_promised": -3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000074", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000074", + "first_gr_date": "2026-05-06", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000063", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000063", + "first_gr_date": "2026-05-07", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000051", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000051", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000070", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000070", + "first_gr_date": "2026-05-12", + "days_vs_promised": 20, + "lead_time_days": 64 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000075", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000075", + "first_gr_date": "2026-05-15", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000061", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000061", + "first_gr_date": "2026-05-18", + "days_vs_promised": -3, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000065", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000065", + "first_gr_date": "2026-05-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000072", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000072", + "first_gr_date": "2026-05-21", + "days_vs_promised": 18, + "lead_time_days": 58 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000062", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000062", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000053", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000053", + "first_gr_date": "2026-05-29", + "days_vs_promised": 0, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000077", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000077", + "first_gr_date": "2026-06-02", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000078", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000078", + "first_gr_date": "2026-06-03", + "days_vs_promised": -3, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000076", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000076", + "first_gr_date": "2026-06-04", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000064", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000064", + "first_gr_date": "2026-06-05", + "days_vs_promised": -1, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000052", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000052", + "first_gr_date": "2026-06-06", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000073", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000073", + "first_gr_date": "2026-06-07", + "days_vs_promised": 30, + "lead_time_days": 68 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000079", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000079", + "first_gr_date": "2026-06-09", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000054", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000054", + "first_gr_date": "2026-06-13", + "days_vs_promised": 0, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000055", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000055", + "first_gr_date": "2026-06-13", + "days_vs_promised": -2, + "lead_time_days": 33 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000066", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000066", + "first_gr_date": "2026-06-16", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000067", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000067", + "first_gr_date": "2026-06-22", + "days_vs_promised": 18, + "lead_time_days": 39 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 14, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0002", + "name": "Cascadia Coffee Traders" + }, + "vendors": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "n_lines": 56, + "n_late": 5, + "on_time_pct": 91.1, + "in_full_pct": 100.0, + "otif_pct": 91.1, + "mean_days_late_all": 0.29, + "mean_days_late_when_late": 3.2, + "median_days_late_when_late": 3, + "max_days_late": 6, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 8.9, + "ge_3d_pct": 5.4, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 12, + "n_late": 4, + "on_time_pct": 66.7, + "in_full_pct": 100.0, + "otif_pct": 66.7, + "mean_days_late_all": 2.08, + "mean_days_late_when_late": 6.2, + "median_days_late_when_late": 3.0, + "max_days_late": 18, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 33.3, + "ge_3d_pct": 16.7, + "ge_7d_pct": 8.3, + "ge_14d_pct": 8.3 + } + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "n_lines": 12, + "n_late": 5, + "on_time_pct": 58.3, + "in_full_pct": 100.0, + "otif_pct": 58.3, + "mean_days_late_all": 6.25, + "mean_days_late_when_late": 15, + "median_days_late_when_late": 18, + "max_days_late": 30, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 41.7, + "ge_3d_pct": 41.7, + "ge_7d_pct": 25.0, + "ge_14d_pct": 25.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 80, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000000", + "po_item": "00010", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "first_gr_date": "2025-06-06", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000001", + "po_item": "00020", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "first_gr_date": "2025-06-15", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000002", + "po_item": "00030", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "first_gr_date": "2025-06-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000003", + "po_item": "00040", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "first_gr_date": "2025-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000004", + "po_item": "00050", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "first_gr_date": "2025-06-21", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000005", + "po_item": "00010", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "first_gr_date": "2025-06-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000006", + "po_item": "00020", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "first_gr_date": "2025-07-09", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000008", + "po_item": "00040", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000009", + "po_item": "00050", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "first_gr_date": "2025-07-21", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000010", + "po_item": "00010", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "first_gr_date": "2025-07-26", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000012", + "po_item": "00030", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000013", + "po_item": "00040", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "first_gr_date": "2025-08-20", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000014", + "po_item": "00050", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "first_gr_date": "2025-08-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000015", + "po_item": "00010", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "first_gr_date": "2025-08-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000016", + "po_item": "00020", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "first_gr_date": "2025-09-25", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000017", + "po_item": "00030", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "first_gr_date": "2025-10-05", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000018", + "po_item": "00040", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "first_gr_date": "2025-10-10", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000019", + "po_item": "00050", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "first_gr_date": "2025-09-27", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000020", + "po_item": "00010", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "first_gr_date": "2025-10-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000021", + "po_item": "00020", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "first_gr_date": "2025-10-19", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000022", + "po_item": "00030", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "first_gr_date": "2025-10-16", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000023", + "po_item": "00040", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-31", + "days_late": 2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000024", + "po_item": "00050", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "first_gr_date": "2025-11-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000025", + "po_item": "00010", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "first_gr_date": "2025-11-17", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000026", + "po_item": "00020", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "first_gr_date": "2025-12-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000027", + "po_item": "00030", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "first_gr_date": "2025-11-29", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000028", + "po_item": "00040", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "first_gr_date": "2025-12-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000029", + "po_item": "00050", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "first_gr_date": "2025-12-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000030", + "po_item": "00010", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-24", + "days_late": 1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000031", + "po_item": "00020", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000032", + "po_item": "00030", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "first_gr_date": "2026-01-17", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000033", + "po_item": "00040", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000034", + "po_item": "00050", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000035", + "po_item": "00010", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000036", + "po_item": "00020", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "first_gr_date": "2026-01-31", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000037", + "po_item": "00030", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "first_gr_date": "2026-02-08", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000038", + "po_item": "00040", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000039", + "po_item": "00050", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "first_gr_date": "2026-03-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000040", + "po_item": "00010", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "first_gr_date": "2026-02-25", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000041", + "po_item": "00020", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000042", + "po_item": "00030", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "first_gr_date": "2026-03-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000043", + "po_item": "00040", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "first_gr_date": "2026-03-22", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000044", + "po_item": "00050", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000045", + "po_item": "00010", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000047", + "po_item": "00030", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-01", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000048", + "po_item": "00040", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "first_gr_date": "2026-04-22", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000049", + "po_item": "00050", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "first_gr_date": "2026-05-06", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000050", + "po_item": "00010", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "first_gr_date": "2026-04-27", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000051", + "po_item": "00020", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000052", + "po_item": "00030", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000053", + "po_item": "00040", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-29", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000054", + "po_item": "00050", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "first_gr_date": "2026-06-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000055", + "po_item": "00010", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "first_gr_date": "2026-06-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000056", + "po_item": "00010", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "first_gr_date": "2026-04-10", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000057", + "po_item": "00020", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "first_gr_date": "2026-04-01", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000059", + "po_item": "00040", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000060", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-14", + "days_late": 1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000061", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-18", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000062", + "po_item": "00020", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000063", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "first_gr_date": "2026-05-07", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000064", + "po_item": "00040", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-05", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000065", + "po_item": "00050", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "first_gr_date": "2026-05-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000066", + "po_item": "00010", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000071", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000074", + "po_item": "00020", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "first_gr_date": "2026-05-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000075", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-15", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000076", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000077", + "po_item": "00050", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "first_gr_date": "2026-06-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000078", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-03", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000079", + "po_item": "00020", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "first_gr_date": "2026-06-09", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_lowland_robusta.json new file mode 100644 index 00000000000..59fb911a279 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_lowland_robusta.json @@ -0,0 +1,2575 @@ +{ + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "durations": [ + 26.2, 39.4, 4.1, 54.9, 20.5, 33.6, 12.3, 67.2, 31.2, 16.4, 42.6, 8.2, 36.1, + 23.0, 28.7, 14.8, 45.1, 21.3, 21.3, 23.8, 25.4, 27.9, 30.3, 21.3, 23.0, + 25.4, 27.1, 29.5, 27.1, 29.5, 31.2, 34.4, 23.0, 26.2, 28.7, 31.2, 19.7, + 23.0, 32.8, 35.3, 23.8, 27.1, 28.7, 32.8, 21.3, 23.8, 25.4, 27.9, 18.0, + 21.3, 23.0, 25.4, 27.1, 25.4, 27.1, 29.5, 31.2, 34.4, 24.6, 26.2, 28.7, + 31.2, 19.7 + ], + "observations": [ + { + "date": "2022-02-08", + "value": 26.2 + }, + { + "date": "2022-04-19", + "value": 39.4 + }, + { + "date": "2022-07-11", + "value": 4.1 + }, + { + "date": "2022-09-28", + "value": 54.9 + }, + { + "date": "2022-12-15", + "value": 20.5 + }, + { + "date": "2023-03-07", + "value": 33.6 + }, + { + "date": "2023-05-22", + "value": 12.3 + }, + { + "date": "2023-08-09", + "value": 67.2 + }, + { + "date": "2023-10-30", + "value": 31.2 + }, + { + "date": "2024-01-16", + "value": 16.4 + }, + { + "date": "2024-03-25", + "value": 42.6 + }, + { + "date": "2024-06-12", + "value": 8.2 + }, + { + "date": "2024-08-28", + "value": 36.1 + }, + { + "date": "2024-11-14", + "value": 23.0 + }, + { + "date": "2025-01-06", + "value": 28.7 + }, + { + "date": "2025-03-18", + "value": 14.8 + }, + { + "date": "2025-05-29", + "value": 45.1 + }, + { + "date": "2025-08-12", + "value": 21.3 + }, + { + "date": "2025-09-04", + "value": 21.3 + }, + { + "date": "2025-09-10", + "value": 23.8 + }, + { + "date": "2025-09-16", + "value": 25.4 + }, + { + "date": "2025-09-22", + "value": 27.9 + }, + { + "date": "2025-09-28", + "value": 30.3 + }, + { + "date": "2025-10-05", + "value": 21.3 + }, + { + "date": "2025-10-11", + "value": 23.0 + }, + { + "date": "2025-10-17", + "value": 25.4 + }, + { + "date": "2025-10-23", + "value": 27.1 + }, + { + "date": "2025-10-29", + "value": 29.5 + }, + { + "date": "2025-11-06", + "value": 27.1 + }, + { + "date": "2025-11-12", + "value": 29.5 + }, + { + "date": "2025-11-18", + "value": 31.2 + }, + { + "date": "2025-11-24", + "value": 34.4 + }, + { + "date": "2025-11-30", + "value": 23.0 + }, + { + "date": "2025-12-04", + "value": 26.2 + }, + { + "date": "2025-12-10", + "value": 28.7 + }, + { + "date": "2025-12-16", + "value": 31.2 + }, + { + "date": "2025-12-22", + "value": 19.7 + }, + { + "date": "2025-12-28", + "value": 23.0 + }, + { + "date": "2026-01-05", + "value": 32.8 + }, + { + "date": "2026-01-11", + "value": 35.3 + }, + { + "date": "2026-01-17", + "value": 23.8 + }, + { + "date": "2026-01-23", + "value": 27.1 + }, + { + "date": "2026-01-29", + "value": 28.7 + }, + { + "date": "2026-02-06", + "value": 32.8 + }, + { + "date": "2026-02-12", + "value": 21.3 + }, + { + "date": "2026-02-18", + "value": 23.8 + }, + { + "date": "2026-02-24", + "value": 25.4 + }, + { + "date": "2026-02-30", + "value": 27.9 + }, + { + "date": "2026-03-04", + "value": 18.0 + }, + { + "date": "2026-03-10", + "value": 21.3 + }, + { + "date": "2026-03-16", + "value": 23.0 + }, + { + "date": "2026-03-22", + "value": 25.4 + }, + { + "date": "2026-03-28", + "value": 27.1 + }, + { + "date": "2026-04-05", + "value": 25.4 + }, + { + "date": "2026-04-11", + "value": 27.1 + }, + { + "date": "2026-04-17", + "value": 29.5 + }, + { + "date": "2026-04-23", + "value": 31.2 + }, + { + "date": "2026-04-29", + "value": 34.4 + }, + { + "date": "2026-05-06", + "value": 24.6 + }, + { + "date": "2026-05-12", + "value": 26.2 + }, + { + "date": "2026-05-18", + "value": 28.7 + }, + { + "date": "2026-05-24", + "value": 31.2 + }, + { + "date": "2026-05-30", + "value": 19.7 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 26.2, + "median": 26.2, + "p10": 26.2, + "p25": 26.2, + "p75": 26.2, + "p90": 26.2, + "n": 1 + }, + { + "month": "2022-04", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-09", + "mean": 54.9, + "median": 54.9, + "p10": 54.9, + "p25": 54.9, + "p75": 54.9, + "p90": 54.9, + "n": 1 + }, + { + "month": "2022-12", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 33.6, + "median": 33.6, + "p10": 33.6, + "p25": 33.6, + "p75": 33.6, + "p90": 33.6, + "n": 1 + }, + { + "month": "2023-05", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2023-08", + "mean": 67.2, + "median": 67.2, + "p10": 67.2, + "p25": 67.2, + "p75": 67.2, + "p90": 67.2, + "n": 1 + }, + { + "month": "2023-10", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-01", + "mean": 16.4, + "median": 16.4, + "p10": 16.4, + "p25": 16.4, + "p75": 16.4, + "p90": 16.4, + "n": 1 + }, + { + "month": "2024-03", + "mean": 42.6, + "median": 42.6, + "p10": 42.6, + "p25": 42.6, + "p75": 42.6, + "p90": 42.6, + "n": 1 + }, + { + "month": "2024-06", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1 + }, + { + "month": "2024-08", + "mean": 36.1, + "median": 36.1, + "p10": 36.1, + "p25": 36.1, + "p75": 36.1, + "p90": 36.1, + "n": 1 + }, + { + "month": "2024-11", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2025-03", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2025-05", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 21.3, + "median": 21.3, + "p10": 21.3, + "p25": 21.3, + "p75": 21.3, + "p90": 21.3, + "n": 1 + }, + { + "month": "2025-09", + "mean": 25.7, + "median": 25.4, + "p10": 22.3, + "p25": 23.8, + "p75": 27.9, + "p90": 29.4, + "n": 5 + }, + { + "month": "2025-10", + "mean": 25.3, + "median": 25.4, + "p10": 22.0, + "p25": 23.0, + "p75": 27.1, + "p90": 28.5, + "n": 5 + }, + { + "month": "2025-11", + "mean": 29.0, + "median": 29.5, + "p10": 24.6, + "p25": 27.1, + "p75": 31.2, + "p90": 33.1, + "n": 5 + }, + { + "month": "2025-12", + "mean": 25.7, + "median": 26.2, + "p10": 21.0, + "p25": 23.0, + "p75": 28.7, + "p90": 30.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 29.5, + "median": 28.7, + "p10": 25.1, + "p25": 27.1, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2026-02", + "mean": 26.2, + "median": 25.4, + "p10": 22.3, + "p25": 23.8, + "p75": 27.9, + "p90": 30.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 23.0, + "median": 23.0, + "p10": 19.4, + "p25": 21.3, + "p75": 25.4, + "p90": 26.4, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.5, + "median": 29.5, + "p10": 26.1, + "p25": 27.1, + "p75": 31.2, + "p90": 33.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 26.1, + "median": 26.2, + "p10": 21.6, + "p25": 24.6, + "p75": 28.7, + "p90": 30.2, + "n": 5 + } + ], + "stats": { + "n": 63, + "mean": 27.4, + "median": 27.1, + "std": 11.4, + "min": 4.1, + "max": 67.2, + "p25": 23.0, + "p75": 31.2, + "p85": 32.8, + "p95": 39.4 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000081", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000081", + "first_gr_date": "2025-08-29", + "days_vs_promised": -1, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000082", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000082", + "first_gr_date": "2025-09-03", + "days_vs_promised": -2, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000080", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000080", + "first_gr_date": "2025-09-08", + "days_vs_promised": -2, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000083", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000083", + "first_gr_date": "2025-09-16", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000084", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000084", + "first_gr_date": "2025-10-01", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000086", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000086", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000088", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000088", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000085", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000085", + "first_gr_date": "2025-10-19", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000087", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000087", + "first_gr_date": "2025-10-22", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000089", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000089", + "first_gr_date": "2025-11-01", + "days_vs_promised": -1, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000090", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000090", + "first_gr_date": "2025-11-06", + "days_vs_promised": -1, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000093", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000093", + "first_gr_date": "2025-11-23", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000094", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000094", + "first_gr_date": "2025-11-25", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000091", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000091", + "first_gr_date": "2025-11-30", + "days_vs_promised": -2, + "lead_time_days": 47 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000092", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000092", + "first_gr_date": "2025-12-07", + "days_vs_promised": -1, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000095", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000095", + "first_gr_date": "2025-12-20", + "days_vs_promised": -3, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000099", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000099", + "first_gr_date": "2025-12-27", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000096", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000096", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000098", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000098", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000097", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000097", + "first_gr_date": "2025-12-30", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000101", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000101", + "first_gr_date": "2026-01-15", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000102", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000102", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000100", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000100", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000122", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000122", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000104", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000104", + "first_gr_date": "2026-02-08", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000103", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000103", + "first_gr_date": "2026-02-13", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000105", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000105", + "first_gr_date": "2026-02-23", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000125", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000125", + "first_gr_date": "2026-02-24", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000123", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000123", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000107", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000107", + "first_gr_date": "2026-03-02", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000124", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000124", + "first_gr_date": "2026-03-07", + "days_vs_promised": -3, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000106", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000106", + "first_gr_date": "2026-03-13", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000126", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000126", + "first_gr_date": "2026-03-14", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000127", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000127", + "first_gr_date": "2026-03-23", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000108", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000108", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000128", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000128", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000110", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000110", + "first_gr_date": "2026-03-25", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000109", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000109", + "first_gr_date": "2026-04-06", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000129", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000129", + "first_gr_date": "2026-04-08", + "days_vs_promised": -3, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000114", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000114", + "first_gr_date": "2026-04-11", + "days_vs_promised": -2, + "lead_time_days": 19 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000111", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000111", + "first_gr_date": "2026-04-12", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000112", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000112", + "first_gr_date": "2026-04-13", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000130", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000130", + "first_gr_date": "2026-04-17", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000115", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000115", + "first_gr_date": "2026-04-23", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000134", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000134", + "first_gr_date": "2026-04-30", + "days_vs_promised": -3, + "lead_time_days": 24 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000113", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000113", + "first_gr_date": "2026-05-01", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000131", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000131", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000117", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000117", + "first_gr_date": "2026-05-05", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000136", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000136", + "first_gr_date": "2026-05-08", + "days_vs_promised": -2, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000132", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000132", + "first_gr_date": "2026-05-09", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000133", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000133", + "first_gr_date": "2026-05-13", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000135", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000135", + "first_gr_date": "2026-05-18", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000116", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000116", + "first_gr_date": "2026-05-21", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000138", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000138", + "first_gr_date": "2026-05-28", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000118", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000118", + "first_gr_date": "2026-05-31", + "days_vs_promised": -1, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000139", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000139", + "first_gr_date": "2026-05-31", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000137", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000137", + "first_gr_date": "2026-06-01", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000120", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000120", + "first_gr_date": "2026-06-05", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000119", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000119", + "first_gr_date": "2026-06-17", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000121", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000121", + "first_gr_date": "2026-06-19", + "days_vs_promised": 0, + "lead_time_days": 37 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 18, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0004", + "name": "Riverbend Reliable Supply" + }, + "vendors": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "n_lines": 42, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "n_lines": 18, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [], + "coverage_pct": 100.0, + "n_lines": 60, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000080", + "po_item": "00010", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "first_gr_date": "2025-09-08", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000081", + "po_item": "00020", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "first_gr_date": "2025-08-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000082", + "po_item": "00030", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "first_gr_date": "2025-09-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000083", + "po_item": "00040", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "first_gr_date": "2025-09-16", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000084", + "po_item": "00050", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "first_gr_date": "2025-10-01", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000085", + "po_item": "00010", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "first_gr_date": "2025-10-19", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000086", + "po_item": "00020", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000087", + "po_item": "00030", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "first_gr_date": "2025-10-22", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000088", + "po_item": "00040", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000089", + "po_item": "00050", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-01", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000090", + "po_item": "00010", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-06", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000091", + "po_item": "00020", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "first_gr_date": "2025-11-30", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000092", + "po_item": "00030", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "first_gr_date": "2025-12-07", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000093", + "po_item": "00040", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "first_gr_date": "2025-11-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000094", + "po_item": "00050", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "first_gr_date": "2025-11-25", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000095", + "po_item": "00010", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-20", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000096", + "po_item": "00020", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000097", + "po_item": "00030", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "first_gr_date": "2025-12-30", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000098", + "po_item": "00040", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000099", + "po_item": "00050", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "first_gr_date": "2025-12-27", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000100", + "po_item": "00010", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000101", + "po_item": "00020", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000102", + "po_item": "00030", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000103", + "po_item": "00040", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-13", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000104", + "po_item": "00050", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "first_gr_date": "2026-02-08", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000105", + "po_item": "00010", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "first_gr_date": "2026-02-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000106", + "po_item": "00020", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "first_gr_date": "2026-03-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000107", + "po_item": "00030", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "first_gr_date": "2026-03-02", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000108", + "po_item": "00040", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000109", + "po_item": "00050", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000110", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-25", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000111", + "po_item": "00020", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "first_gr_date": "2026-04-12", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000112", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-13", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000113", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "first_gr_date": "2026-05-01", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000114", + "po_item": "00050", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-11", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000115", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "first_gr_date": "2026-04-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000116", + "po_item": "00020", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-21", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000117", + "po_item": "00030", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "first_gr_date": "2026-05-05", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000118", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "first_gr_date": "2026-05-31", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000119", + "po_item": "00050", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "first_gr_date": "2026-06-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000120", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "first_gr_date": "2026-06-05", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000121", + "po_item": "00020", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "first_gr_date": "2026-06-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000122", + "po_item": "00010", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000123", + "po_item": "00020", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000124", + "po_item": "00030", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-07", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000125", + "po_item": "00040", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "first_gr_date": "2026-02-24", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000126", + "po_item": "00050", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "first_gr_date": "2026-03-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000127", + "po_item": "00010", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-23", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000128", + "po_item": "00020", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000129", + "po_item": "00030", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-08", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000130", + "po_item": "00040", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "first_gr_date": "2026-04-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000131", + "po_item": "00050", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000132", + "po_item": "00010", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000133", + "po_item": "00020", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "first_gr_date": "2026-05-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000134", + "po_item": "00030", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "first_gr_date": "2026-04-30", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000135", + "po_item": "00040", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000136", + "po_item": "00050", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "first_gr_date": "2026-05-08", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000137", + "po_item": "00010", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "first_gr_date": "2026-06-01", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000138", + "po_item": "00020", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "first_gr_date": "2026-05-28", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000139", + "po_item": "00030", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "first_gr_date": "2026-05-31", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_washed_bourbon.json new file mode 100644 index 00000000000..632d0e613a2 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/procurement_washed_bourbon.json @@ -0,0 +1,2251 @@ +{ + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "durations": [ + 28.7, 13.1, 50.8, 5.7, 32.8, 20.5, 39.4, 9.8, 24.6, 11.5, 24.6, 15.6, 18.0, + 18.9, 20.5, 18.9, 20.5, 22.1, 23.8, 25.4, 18.9, 20.5, 22.1, 23.8, 25.4, + 18.0, 19.7, 21.3, 23.0, 14.8, 23.0, 24.6, 26.2, 18.0, 19.7, 22.1, 24.6, + 15.6, 18.0, 18.9, 27.9, 18.9, 20.5, 22.1, 23.8, 16.4, 18.9, 20.5, 22.1, + 23.8, 16.4, 18.0, 19.7, 21.3, 23.0 + ], + "observations": [ + { + "date": "2022-05-03", + "value": 28.7 + }, + { + "date": "2022-10-18", + "value": 13.1 + }, + { + "date": "2023-01-24", + "value": 50.8 + }, + { + "date": "2023-06-15", + "value": 5.7 + }, + { + "date": "2023-09-28", + "value": 32.8 + }, + { + "date": "2024-02-12", + "value": 20.5 + }, + { + "date": "2024-05-07", + "value": 39.4 + }, + { + "date": "2024-09-19", + "value": 9.8 + }, + { + "date": "2025-02-04", + "value": 24.6 + }, + { + "date": "2025-06-10", + "value": 11.5 + }, + { + "date": "2025-09-06", + "value": 24.6 + }, + { + "date": "2025-09-12", + "value": 15.6 + }, + { + "date": "2025-09-18", + "value": 18.0 + }, + { + "date": "2025-09-24", + "value": 18.9 + }, + { + "date": "2025-09-30", + "value": 20.5 + }, + { + "date": "2025-10-04", + "value": 18.9 + }, + { + "date": "2025-10-10", + "value": 20.5 + }, + { + "date": "2025-10-16", + "value": 22.1 + }, + { + "date": "2025-10-22", + "value": 23.8 + }, + { + "date": "2025-10-28", + "value": 25.4 + }, + { + "date": "2025-11-05", + "value": 18.9 + }, + { + "date": "2025-11-11", + "value": 20.5 + }, + { + "date": "2025-11-17", + "value": 22.1 + }, + { + "date": "2025-11-23", + "value": 23.8 + }, + { + "date": "2025-11-29", + "value": 25.4 + }, + { + "date": "2025-12-06", + "value": 18.0 + }, + { + "date": "2025-12-12", + "value": 19.7 + }, + { + "date": "2025-12-18", + "value": 21.3 + }, + { + "date": "2025-12-24", + "value": 23.0 + }, + { + "date": "2025-12-30", + "value": 14.8 + }, + { + "date": "2026-01-04", + "value": 23.0 + }, + { + "date": "2026-01-10", + "value": 24.6 + }, + { + "date": "2026-01-16", + "value": 26.2 + }, + { + "date": "2026-01-22", + "value": 18.0 + }, + { + "date": "2026-01-28", + "value": 19.7 + }, + { + "date": "2026-02-05", + "value": 22.1 + }, + { + "date": "2026-02-11", + "value": 24.6 + }, + { + "date": "2026-02-17", + "value": 15.6 + }, + { + "date": "2026-02-23", + "value": 18.0 + }, + { + "date": "2026-02-29", + "value": 18.9 + }, + { + "date": "2026-03-06", + "value": 27.9 + }, + { + "date": "2026-03-12", + "value": 18.9 + }, + { + "date": "2026-03-18", + "value": 20.5 + }, + { + "date": "2026-03-24", + "value": 22.1 + }, + { + "date": "2026-03-30", + "value": 23.8 + }, + { + "date": "2026-04-04", + "value": 16.4 + }, + { + "date": "2026-04-10", + "value": 18.9 + }, + { + "date": "2026-04-16", + "value": 20.5 + }, + { + "date": "2026-04-22", + "value": 22.1 + }, + { + "date": "2026-04-28", + "value": 23.8 + }, + { + "date": "2026-05-05", + "value": 16.4 + }, + { + "date": "2026-05-11", + "value": 18.0 + }, + { + "date": "2026-05-17", + "value": 19.7 + }, + { + "date": "2026-05-23", + "value": 21.3 + }, + { + "date": "2026-05-29", + "value": 23.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 13.1, + "median": 13.1, + "p10": 13.1, + "p25": 13.1, + "p75": 13.1, + "p90": 13.1, + "n": 1 + }, + { + "month": "2023-01", + "mean": 50.8, + "median": 50.8, + "p10": 50.8, + "p25": 50.8, + "p75": 50.8, + "p90": 50.8, + "n": 1 + }, + { + "month": "2023-06", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 32.8, + "median": 32.8, + "p10": 32.8, + "p25": 32.8, + "p75": 32.8, + "p90": 32.8, + "n": 1 + }, + { + "month": "2024-02", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2024-09", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2025-02", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2025-06", + "mean": 11.5, + "median": 11.5, + "p10": 11.5, + "p25": 11.5, + "p75": 11.5, + "p90": 11.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 19.5, + "median": 18.9, + "p10": 16.6, + "p25": 18.0, + "p75": 20.5, + "p90": 23.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 22.1, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 24.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 22.1, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 24.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 19.4, + "median": 19.7, + "p10": 16.1, + "p25": 18.0, + "p75": 21.3, + "p90": 22.3, + "n": 5 + }, + { + "month": "2026-01", + "mean": 22.3, + "median": 23.0, + "p10": 18.7, + "p25": 19.7, + "p75": 24.6, + "p90": 25.6, + "n": 5 + }, + { + "month": "2026-02", + "mean": 19.8, + "median": 18.9, + "p10": 16.6, + "p25": 18.0, + "p75": 22.1, + "p90": 23.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 22.6, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 26.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 20.3, + "median": 20.5, + "p10": 17.4, + "p25": 18.9, + "p75": 22.1, + "p90": 23.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 19.7, + "median": 19.7, + "p10": 17.1, + "p25": 18.0, + "p75": 21.3, + "p90": 22.3, + "n": 5 + } + ], + "stats": { + "n": 55, + "mean": 21.4, + "median": 20.5, + "std": 8.0, + "min": 5.7, + "max": 50.8, + "p25": 18.0, + "p75": 23.8, + "p85": 24.6, + "p95": 28.7 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000142", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000142", + "first_gr_date": "2025-10-29", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000141", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000141", + "first_gr_date": "2025-11-02", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000140", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000140", + "first_gr_date": "2025-11-07", + "days_vs_promised": 24, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000143", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000143", + "first_gr_date": "2025-11-07", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000144", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000144", + "first_gr_date": "2025-11-10", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000146", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000146", + "first_gr_date": "2025-12-03", + "days_vs_promised": -2, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000145", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000145", + "first_gr_date": "2025-12-11", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000148", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000148", + "first_gr_date": "2025-12-21", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000147", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000147", + "first_gr_date": "2025-12-23", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000150", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000150", + "first_gr_date": "2026-01-06", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000149", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000149", + "first_gr_date": "2026-01-07", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000151", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000151", + "first_gr_date": "2026-01-13", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000153", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000153", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000155", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000155", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000152", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000152", + "first_gr_date": "2026-01-26", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000154", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000154", + "first_gr_date": "2026-01-31", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000156", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000156", + "first_gr_date": "2026-02-14", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000158", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000158", + "first_gr_date": "2026-02-15", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000157", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000157", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000159", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000159", + "first_gr_date": "2026-03-06", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000176", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000176", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000160", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000160", + "first_gr_date": "2026-03-08", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000175", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000175", + "first_gr_date": "2026-03-10", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000178", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000178", + "first_gr_date": "2026-03-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000161", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000161", + "first_gr_date": "2026-03-20", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000179", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000179", + "first_gr_date": "2026-03-29", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000162", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000162", + "first_gr_date": "2026-04-01", + "days_vs_promised": 12, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000180", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000180", + "first_gr_date": "2026-04-02", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000177", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000177", + "first_gr_date": "2026-04-05", + "days_vs_promised": 2, + "lead_time_days": 47 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000165", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000165", + "first_gr_date": "2026-04-07", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000164", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000164", + "first_gr_date": "2026-04-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000163", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000163", + "first_gr_date": "2026-04-10", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000166", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000166", + "first_gr_date": "2026-04-10", + "days_vs_promised": -1, + "lead_time_days": 24 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000167", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000167", + "first_gr_date": "2026-04-16", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000181", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000181", + "first_gr_date": "2026-04-24", + "days_vs_promised": 0, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000182", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000182", + "first_gr_date": "2026-04-25", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000183", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000183", + "first_gr_date": "2026-04-26", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000168", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000168", + "first_gr_date": "2026-04-30", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000171", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000171", + "first_gr_date": "2026-05-11", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000185", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000185", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000184", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000184", + "first_gr_date": "2026-05-16", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000169", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000169", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000170", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000170", + "first_gr_date": "2026-05-27", + "days_vs_promised": -2, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000174", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000174", + "first_gr_date": "2026-06-03", + "days_vs_promised": -2, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000172", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000172", + "first_gr_date": "2026-06-09", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000186", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000186", + "first_gr_date": "2026-06-15", + "days_vs_promised": 5, + "lead_time_days": 55 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000189", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000189", + "first_gr_date": "2026-06-17", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000187", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000187", + "first_gr_date": "2026-06-18", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000188", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000188", + "first_gr_date": "2026-06-21", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000173", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000173", + "first_gr_date": "2026-07-02", + "days_vs_promised": 8, + "lead_time_days": 58 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0005", + "name": "Midland Mid-Tier Partners" + }, + "vendors": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "n_lines": 35, + "n_late": 4, + "on_time_pct": 88.6, + "in_full_pct": 100.0, + "otif_pct": 88.6, + "mean_days_late_all": 1.29, + "mean_days_late_when_late": 11.2, + "median_days_late_when_late": 10.0, + "max_days_late": 24, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 11.4, + "ge_3d_pct": 8.6, + "ge_7d_pct": 8.6, + "ge_14d_pct": 2.9 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 15, + "n_late": 3, + "on_time_pct": 80.0, + "in_full_pct": 100.0, + "otif_pct": 80.0, + "mean_days_late_all": 0.53, + "mean_days_late_when_late": 2.7, + "median_days_late_when_late": 2, + "max_days_late": 5, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 20.0, + "ge_3d_pct": 6.7, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 50, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000141", + "po_item": "00020", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000142", + "po_item": "00030", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-29", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000143", + "po_item": "00040", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000144", + "po_item": "00050", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "first_gr_date": "2025-11-10", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000145", + "po_item": "00010", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "first_gr_date": "2025-12-11", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000146", + "po_item": "00020", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "first_gr_date": "2025-12-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000147", + "po_item": "00030", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000148", + "po_item": "00040", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "first_gr_date": "2025-12-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000149", + "po_item": "00050", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "first_gr_date": "2026-01-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000150", + "po_item": "00010", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "first_gr_date": "2026-01-06", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000151", + "po_item": "00020", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "first_gr_date": "2026-01-13", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000152", + "po_item": "00030", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "first_gr_date": "2026-01-26", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000153", + "po_item": "00040", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000154", + "po_item": "00050", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "first_gr_date": "2026-01-31", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000155", + "po_item": "00010", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000156", + "po_item": "00020", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "first_gr_date": "2026-02-14", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000157", + "po_item": "00030", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000158", + "po_item": "00040", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "first_gr_date": "2026-02-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000159", + "po_item": "00050", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "first_gr_date": "2026-03-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000160", + "po_item": "00010", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "first_gr_date": "2026-03-08", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000163", + "po_item": "00040", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000164", + "po_item": "00050", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-09", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000165", + "po_item": "00010", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000166", + "po_item": "00020", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-10", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000167", + "po_item": "00030", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000168", + "po_item": "00040", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "first_gr_date": "2026-04-30", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000169", + "po_item": "00050", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000170", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-27", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000171", + "po_item": "00020", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "first_gr_date": "2026-05-11", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000172", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "first_gr_date": "2026-06-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000174", + "po_item": "00050", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "first_gr_date": "2026-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000175", + "po_item": "00010", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000176", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000178", + "po_item": "00040", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-19", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000179", + "po_item": "00050", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "first_gr_date": "2026-03-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000180", + "po_item": "00010", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "first_gr_date": "2026-04-02", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000181", + "po_item": "00020", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "first_gr_date": "2026-04-24", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000182", + "po_item": "00030", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "first_gr_date": "2026-04-25", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000183", + "po_item": "00040", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-26", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000184", + "po_item": "00050", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "first_gr_date": "2026-05-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000185", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000187", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "first_gr_date": "2026-06-18", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000188", + "po_item": "00040", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "first_gr_date": "2026-06-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_green_blend.json new file mode 100644 index 00000000000..608c3bd3dc0 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_green_blend.json @@ -0,0 +1,924 @@ +{ + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "durations": [ + 2.5, 4.1, 1.6, 5.7, 3.3, 4.9, 2.5, 11.5, 3.3, 6.6, 2.5, 4.1, 0.8, 4.9, 2.5, + 3.3, 3.3, 3.3, 2.5, 3.3, 3.3, 3.3, 3.3, 4.1, 4.1, 4.1, 3.3, 4.1, 4.1, 2.5, + 3.3, 4.1, 2.5, 2.5, 4.1, 2.5, 3.3, 3.3, 2.5, 2.5, 3.3, 3.3, 3.3, 3.3, 4.1, + 4.1, 3.3, 3.3, 4.1, 4.1 + ], + "observations": [ + { + "date": "2022-04-18", + "value": 2.5 + }, + { + "date": "2022-07-05", + "value": 4.1 + }, + { + "date": "2022-10-12", + "value": 1.6 + }, + { + "date": "2023-01-20", + "value": 5.7 + }, + { + "date": "2023-04-15", + "value": 3.3 + }, + { + "date": "2023-07-28", + "value": 4.9 + }, + { + "date": "2023-10-05", + "value": 2.5 + }, + { + "date": "2024-01-12", + "value": 11.5 + }, + { + "date": "2024-04-22", + "value": 3.3 + }, + { + "date": "2024-07-10", + "value": 6.6 + }, + { + "date": "2024-10-18", + "value": 2.5 + }, + { + "date": "2025-01-25", + "value": 4.1 + }, + { + "date": "2025-05-08", + "value": 0.8 + }, + { + "date": "2025-08-15", + "value": 4.9 + }, + { + "date": "2025-09-04", + "value": 2.5 + }, + { + "date": "2025-09-10", + "value": 3.3 + }, + { + "date": "2025-09-16", + "value": 3.3 + }, + { + "date": "2025-09-22", + "value": 3.3 + }, + { + "date": "2025-10-05", + "value": 2.5 + }, + { + "date": "2025-10-11", + "value": 3.3 + }, + { + "date": "2025-10-17", + "value": 3.3 + }, + { + "date": "2025-10-23", + "value": 3.3 + }, + { + "date": "2025-11-06", + "value": 3.3 + }, + { + "date": "2025-11-12", + "value": 4.1 + }, + { + "date": "2025-11-18", + "value": 4.1 + }, + { + "date": "2025-11-24", + "value": 4.1 + }, + { + "date": "2025-12-04", + "value": 3.3 + }, + { + "date": "2025-12-10", + "value": 4.1 + }, + { + "date": "2025-12-16", + "value": 4.1 + }, + { + "date": "2025-12-22", + "value": 2.5 + }, + { + "date": "2026-01-05", + "value": 3.3 + }, + { + "date": "2026-01-11", + "value": 4.1 + }, + { + "date": "2026-01-17", + "value": 2.5 + }, + { + "date": "2026-01-23", + "value": 2.5 + }, + { + "date": "2026-02-06", + "value": 4.1 + }, + { + "date": "2026-02-12", + "value": 2.5 + }, + { + "date": "2026-02-18", + "value": 3.3 + }, + { + "date": "2026-02-24", + "value": 3.3 + }, + { + "date": "2026-03-04", + "value": 2.5 + }, + { + "date": "2026-03-10", + "value": 2.5 + }, + { + "date": "2026-03-16", + "value": 3.3 + }, + { + "date": "2026-03-22", + "value": 3.3 + }, + { + "date": "2026-04-05", + "value": 3.3 + }, + { + "date": "2026-04-11", + "value": 3.3 + }, + { + "date": "2026-04-17", + "value": 4.1 + }, + { + "date": "2026-04-23", + "value": 4.1 + }, + { + "date": "2026-05-06", + "value": 3.3 + }, + { + "date": "2026-05-12", + "value": 3.3 + }, + { + "date": "2026-05-18", + "value": 4.1 + }, + { + "date": "2026-05-24", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-10", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2023-10", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 11.5, + "median": 11.5, + "p10": 11.5, + "p25": 11.5, + "p75": 11.5, + "p90": 11.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2024-10", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-05", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.9, + "median": 4.1, + "p10": 3.5, + "p25": 3.9, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.5, + "median": 3.7, + "p10": 2.7, + "p25": 3.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.1, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.5, + "p90": 3.9, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.3, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.5, + "p90": 3.9, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.7, + "median": 3.7, + "p10": 3.3, + "p25": 3.3, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.7, + "median": 3.7, + "p10": 3.3, + "p25": 3.3, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 3.6, + "median": 3.3, + "std": 1.8, + "min": 0.8, + "max": 11.5, + "p25": 2.5, + "p75": 4.1, + "p85": 4.1, + "p95": 4.9 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 50, + "n_movements": null, + "yield_data": { + "values": [ + 98.2, 99.5, 97.8, 100.2, 96.5, 99.0, 98.8, 97.2, 99.5, 100.8, 98.0, 97.5, + 99.2, 98.5, 98.4, 98.6, 98.9, 99.1, 98.3, 98.5, 98.8, 99.1, 99.0, 99.3, + 99.6, 98.2, 99.0, 99.3, 97.9, 98.2, 98.9, 97.6, 97.9, 98.1, 98.1, 98.4, + 98.6, 98.9, 98.1, 98.3, 98.5, 98.8, 98.8, 99.0, 99.3, 99.6, 98.7, 99.0, + 99.3, 97.9 + ], + "observations": [ + { + "date": "2022-04-21", + "value": 98.2 + }, + { + "date": "2022-07-10", + "value": 99.5 + }, + { + "date": "2022-10-14", + "value": 97.8 + }, + { + "date": "2023-01-27", + "value": 100.2 + }, + { + "date": "2023-04-19", + "value": 96.5 + }, + { + "date": "2023-08-03", + "value": 99.0 + }, + { + "date": "2023-10-08", + "value": 98.8 + }, + { + "date": "2024-01-26", + "value": 97.2 + }, + { + "date": "2024-04-26", + "value": 99.5 + }, + { + "date": "2024-07-18", + "value": 100.8 + }, + { + "date": "2024-10-21", + "value": 98.0 + }, + { + "date": "2025-01-30", + "value": 97.5 + }, + { + "date": "2025-05-09", + "value": 99.2 + }, + { + "date": "2025-08-21", + "value": 98.5 + }, + { + "date": "2025-09-05", + "value": 98.4 + }, + { + "date": "2025-09-11", + "value": 98.6 + }, + { + "date": "2025-09-17", + "value": 98.9 + }, + { + "date": "2025-09-23", + "value": 99.1 + }, + { + "date": "2025-10-06", + "value": 98.3 + }, + { + "date": "2025-10-12", + "value": 98.5 + }, + { + "date": "2025-10-18", + "value": 98.8 + }, + { + "date": "2025-10-24", + "value": 99.1 + }, + { + "date": "2025-11-04", + "value": 99.0 + }, + { + "date": "2025-11-10", + "value": 99.3 + }, + { + "date": "2025-11-16", + "value": 99.6 + }, + { + "date": "2025-11-22", + "value": 98.2 + }, + { + "date": "2025-12-05", + "value": 99.0 + }, + { + "date": "2025-12-11", + "value": 99.3 + }, + { + "date": "2025-12-17", + "value": 97.9 + }, + { + "date": "2025-12-23", + "value": 98.2 + }, + { + "date": "2026-01-06", + "value": 98.9 + }, + { + "date": "2026-01-12", + "value": 97.6 + }, + { + "date": "2026-01-18", + "value": 97.9 + }, + { + "date": "2026-01-24", + "value": 98.1 + }, + { + "date": "2026-02-04", + "value": 98.1 + }, + { + "date": "2026-02-10", + "value": 98.4 + }, + { + "date": "2026-02-16", + "value": 98.6 + }, + { + "date": "2026-02-22", + "value": 98.9 + }, + { + "date": "2026-03-05", + "value": 98.1 + }, + { + "date": "2026-03-11", + "value": 98.3 + }, + { + "date": "2026-03-17", + "value": 98.5 + }, + { + "date": "2026-03-23", + "value": 98.8 + }, + { + "date": "2026-04-06", + "value": 98.8 + }, + { + "date": "2026-04-12", + "value": 99.0 + }, + { + "date": "2026-04-18", + "value": 99.3 + }, + { + "date": "2026-04-24", + "value": 99.6 + }, + { + "date": "2026-05-04", + "value": 98.7 + }, + { + "date": "2026-05-10", + "value": 99.0 + }, + { + "date": "2026-05-16", + "value": 99.3 + }, + { + "date": "2026-05-22", + "value": 97.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-10", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 96.5, + "median": 96.5, + "p10": 96.5, + "p25": 96.5, + "p75": 96.5, + "p90": 96.5, + "n": 1 + }, + { + "month": "2023-08", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2024-04", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-07", + "mean": 100.8, + "median": 100.8, + "p10": 100.8, + "p25": 100.8, + "p75": 100.8, + "p90": 100.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2025-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 98.8, + "median": 98.8, + "p10": 98.5, + "p25": 98.6, + "p75": 99.0, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 98.7, + "median": 98.7, + "p10": 98.4, + "p25": 98.5, + "p75": 98.9, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.0, + "median": 99.2, + "p10": 98.4, + "p25": 98.8, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 98.6, + "median": 98.6, + "p10": 98.0, + "p25": 98.1, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.1, + "median": 98.0, + "p10": 97.7, + "p25": 97.8, + "p75": 98.3, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 98.5, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.7, + "p90": 98.8, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.4, + "median": 98.4, + "p10": 98.2, + "p25": 98.3, + "p75": 98.6, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 98.7, + "median": 98.9, + "p10": 98.1, + "p25": 98.5, + "p75": 99.1, + "p90": 99.2, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 98.7, + "median": 98.8, + "std": 0.7, + "min": 96.5, + "max": 100.8, + "p25": 98.2, + "p75": 99.1, + "p85": 99.3, + "p95": 99.6 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_harbor_dark_roast.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_harbor_dark_roast.json new file mode 100644 index 00000000000..de3cb1d23c1 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_duration_harbor_dark_roast.json @@ -0,0 +1,1148 @@ +{ + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "durations": [ + 1.6, 2.5, 0.8, 3.3, 1.6, 4.1, 2.5, 5.7, 1.6, 3.3, 0.8, 2.5, 8.2, 2.5, 1.6, + 4.1, 0.0, 3.3, 2.5, 1.6, 4.9, 2.5, 3.3, 3.3, 2.5, 2.5, 3.3, 1.6, 2.5, 2.5, + 1.6, 1.6, 2.5, 2.5, 2.5, 2.5, 2.5, 3.3, 2.5, 2.5, 2.5, 3.3, 3.3, 3.3, 3.3, + 2.5, 2.5, 3.3, 1.6, 2.5, 2.5, 1.6, 1.6, 2.5, 2.5, 2.5, 2.5, 2.5 + ], + "observations": [ + { + "date": "2022-05-20", + "value": 1.6 + }, + { + "date": "2022-06-10", + "value": 2.5 + }, + { + "date": "2022-07-15", + "value": 0.8 + }, + { + "date": "2022-08-22", + "value": 3.3 + }, + { + "date": "2022-10-05", + "value": 1.6 + }, + { + "date": "2022-11-18", + "value": 4.1 + }, + { + "date": "2023-01-10", + "value": 2.5 + }, + { + "date": "2023-03-25", + "value": 5.7 + }, + { + "date": "2023-05-12", + "value": 1.6 + }, + { + "date": "2023-07-08", + "value": 3.3 + }, + { + "date": "2023-09-15", + "value": 0.8 + }, + { + "date": "2023-11-22", + "value": 2.5 + }, + { + "date": "2024-01-18", + "value": 8.2 + }, + { + "date": "2024-03-08", + "value": 2.5 + }, + { + "date": "2024-05-15", + "value": 1.6 + }, + { + "date": "2024-07-22", + "value": 4.1 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 3.3 + }, + { + "date": "2025-01-15", + "value": 2.5 + }, + { + "date": "2025-03-20", + "value": 1.6 + }, + { + "date": "2025-05-28", + "value": 4.9 + }, + { + "date": "2025-08-05", + "value": 2.5 + }, + { + "date": "2025-09-05", + "value": 3.3 + }, + { + "date": "2025-09-11", + "value": 3.3 + }, + { + "date": "2025-09-17", + "value": 2.5 + }, + { + "date": "2025-09-23", + "value": 2.5 + }, + { + "date": "2025-10-06", + "value": 3.3 + }, + { + "date": "2025-10-12", + "value": 1.6 + }, + { + "date": "2025-10-18", + "value": 2.5 + }, + { + "date": "2025-10-24", + "value": 2.5 + }, + { + "date": "2025-11-04", + "value": 1.6 + }, + { + "date": "2025-11-10", + "value": 1.6 + }, + { + "date": "2025-11-16", + "value": 2.5 + }, + { + "date": "2025-11-22", + "value": 2.5 + }, + { + "date": "2025-12-05", + "value": 2.5 + }, + { + "date": "2025-12-11", + "value": 2.5 + }, + { + "date": "2025-12-17", + "value": 2.5 + }, + { + "date": "2025-12-23", + "value": 3.3 + }, + { + "date": "2026-01-06", + "value": 2.5 + }, + { + "date": "2026-01-12", + "value": 2.5 + }, + { + "date": "2026-01-18", + "value": 2.5 + }, + { + "date": "2026-01-24", + "value": 3.3 + }, + { + "date": "2026-02-04", + "value": 3.3 + }, + { + "date": "2026-02-10", + "value": 3.3 + }, + { + "date": "2026-02-16", + "value": 3.3 + }, + { + "date": "2026-02-22", + "value": 2.5 + }, + { + "date": "2026-03-05", + "value": 2.5 + }, + { + "date": "2026-03-11", + "value": 3.3 + }, + { + "date": "2026-03-17", + "value": 1.6 + }, + { + "date": "2026-03-23", + "value": 2.5 + }, + { + "date": "2026-04-06", + "value": 2.5 + }, + { + "date": "2026-04-12", + "value": 1.6 + }, + { + "date": "2026-04-18", + "value": 1.6 + }, + { + "date": "2026-04-24", + "value": 2.5 + }, + { + "date": "2026-05-04", + "value": 2.5 + }, + { + "date": "2026-05-10", + "value": 2.5 + }, + { + "date": "2026-05-16", + "value": 2.5 + }, + { + "date": "2026-05-22", + "value": 2.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-06", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2022-10", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-07", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-09", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2023-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1 + }, + { + "month": "2024-03", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2024-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2025-05", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2025-08", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-10", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.0, + "median": 2.0, + "p10": 1.6, + "p25": 1.6, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.0, + "median": 2.0, + "p10": 1.6, + "p25": 1.6, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 2.6, + "median": 2.5, + "std": 1.4, + "min": 0.0, + "max": 8.2, + "p25": 2.5, + "p75": 3.3, + "p85": 3.3, + "p95": 4.1 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 58, + "n_movements": null, + "yield_data": { + "values": [ + 99.0, 98.5, 99.8, 97.2, 99.5, 98.0, 100.2, 98.8, 99.2, 97.5, 99.0, 98.5, + 100.5, 99.2, 98.0, 97.8, 99.5, 98.2, 99.0, 98.8, 99.5, 97.0, 98.9, 99.1, + 99.4, 99.6, 98.8, 99.0, 99.3, 99.6, 99.5, 99.8, 100.1, 98.7, 99.5, 99.8, + 98.4, 98.7, 99.4, 98.1, 98.4, 98.6, 98.6, 98.9, 99.1, 99.4, 98.6, 98.8, + 99.0, 99.3, 99.3, 99.5, 99.8, 100.1, 99.2, 99.5, 99.8, 98.4 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 99.0 + }, + { + "date": "2022-06-13", + "value": 98.5 + }, + { + "date": "2022-07-16", + "value": 99.8 + }, + { + "date": "2022-08-26", + "value": 97.2 + }, + { + "date": "2022-10-07", + "value": 99.5 + }, + { + "date": "2022-11-23", + "value": 98.0 + }, + { + "date": "2023-01-13", + "value": 100.2 + }, + { + "date": "2023-04-01", + "value": 98.8 + }, + { + "date": "2023-05-14", + "value": 99.2 + }, + { + "date": "2023-07-12", + "value": 97.5 + }, + { + "date": "2023-09-16", + "value": 99.0 + }, + { + "date": "2023-11-25", + "value": 98.5 + }, + { + "date": "2024-01-28", + "value": 100.5 + }, + { + "date": "2024-03-11", + "value": 99.2 + }, + { + "date": "2024-05-17", + "value": 98.0 + }, + { + "date": "2024-07-27", + "value": 97.8 + }, + { + "date": "2024-09-10", + "value": 99.5 + }, + { + "date": "2024-11-09", + "value": 98.2 + }, + { + "date": "2025-01-18", + "value": 99.0 + }, + { + "date": "2025-03-22", + "value": 98.8 + }, + { + "date": "2025-06-03", + "value": 99.5 + }, + { + "date": "2025-08-08", + "value": 97.0 + }, + { + "date": "2025-09-05", + "value": 98.9 + }, + { + "date": "2025-09-11", + "value": 99.1 + }, + { + "date": "2025-09-17", + "value": 99.4 + }, + { + "date": "2025-09-23", + "value": 99.6 + }, + { + "date": "2025-10-06", + "value": 98.8 + }, + { + "date": "2025-10-12", + "value": 99.0 + }, + { + "date": "2025-10-18", + "value": 99.3 + }, + { + "date": "2025-10-24", + "value": 99.6 + }, + { + "date": "2025-11-04", + "value": 99.5 + }, + { + "date": "2025-11-10", + "value": 99.8 + }, + { + "date": "2025-11-16", + "value": 100.1 + }, + { + "date": "2025-11-22", + "value": 98.7 + }, + { + "date": "2025-12-05", + "value": 99.5 + }, + { + "date": "2025-12-11", + "value": 99.8 + }, + { + "date": "2025-12-17", + "value": 98.4 + }, + { + "date": "2025-12-23", + "value": 98.7 + }, + { + "date": "2026-01-06", + "value": 99.4 + }, + { + "date": "2026-01-12", + "value": 98.1 + }, + { + "date": "2026-01-18", + "value": 98.4 + }, + { + "date": "2026-01-24", + "value": 98.6 + }, + { + "date": "2026-02-04", + "value": 98.6 + }, + { + "date": "2026-02-10", + "value": 98.9 + }, + { + "date": "2026-02-16", + "value": 99.1 + }, + { + "date": "2026-02-22", + "value": 99.4 + }, + { + "date": "2026-03-05", + "value": 98.6 + }, + { + "date": "2026-03-11", + "value": 98.8 + }, + { + "date": "2026-03-17", + "value": 99.0 + }, + { + "date": "2026-03-23", + "value": 99.3 + }, + { + "date": "2026-04-06", + "value": 99.3 + }, + { + "date": "2026-04-12", + "value": 99.5 + }, + { + "date": "2026-04-18", + "value": 99.8 + }, + { + "date": "2026-04-24", + "value": 100.1 + }, + { + "date": "2026-05-04", + "value": 99.2 + }, + { + "date": "2026-05-10", + "value": 99.5 + }, + { + "date": "2026-05-16", + "value": 99.8 + }, + { + "date": "2026-05-22", + "value": 98.4 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.8, + "median": 99.8, + "p10": 99.8, + "p25": 99.8, + "p75": 99.8, + "p90": 99.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-11", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2023-07", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 100.5, + "median": 100.5, + "p10": 100.5, + "p25": 100.5, + "p75": 100.5, + "p90": 100.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-11", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 97.0, + "median": 97.0, + "p10": 97.0, + "p25": 97.0, + "p75": 97.0, + "p90": 97.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 99.3, + "median": 99.3, + "p10": 99.0, + "p25": 99.1, + "p75": 99.5, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.5, + "median": 99.7, + "p10": 98.9, + "p25": 99.3, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 99.1, + "median": 99.1, + "p10": 98.5, + "p25": 98.6, + "p75": 99.6, + "p90": 99.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.6, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.8, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-02", + "mean": 99.0, + "median": 99.0, + "p10": 98.7, + "p25": 98.8, + "p75": 99.2, + "p90": 99.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.9, + "median": 98.9, + "p10": 98.7, + "p25": 98.8, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.7, + "median": 99.7, + "p10": 99.4, + "p25": 99.5, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 99.2, + "median": 99.4, + "p10": 98.6, + "p25": 99.0, + "p75": 99.6, + "p90": 99.7, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 99.0, + "median": 99.1, + "std": 0.7, + "min": 97.0, + "max": 100.5, + "p25": 98.6, + "p75": 99.5, + "p85": 99.7, + "p95": 100.1 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_to_qa_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_to_qa_pla.json new file mode 100644 index 00000000000..a7af38894ba --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/prod_to_qa_pla.json @@ -0,0 +1,581 @@ +{ + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "durations": [ + 1.6, 0.8, 2.5, 1.6, 4.1, 1.6, 3.3, 2.5, 4.9, 1.6, 10.7, 2.5, 5.7, 0.8, 3.3, + 4.1, 1.6, 0.0, 2.5, 6.6, 1.6, 4.1, 1.6, 2.5, 2.5, 2.5, 2.5, 2.5, 3.3, 3.3, + 2.5, 2.5, 2.5, 3.3, 2.5, 2.5, 2.5, 1.6, 3.3, 3.3, 2.5, 2.5, 3.3, 1.6, 2.5, + 2.5, 2.5, 2.5, 2.5, 3.3, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 1.6 + }, + { + "date": "2022-06-13", + "value": 0.8 + }, + { + "date": "2022-07-16", + "value": 2.5 + }, + { + "date": "2022-08-26", + "value": 1.6 + }, + { + "date": "2022-10-07", + "value": 4.1 + }, + { + "date": "2022-11-23", + "value": 1.6 + }, + { + "date": "2023-01-13", + "value": 3.3 + }, + { + "date": "2023-04-01", + "value": 2.5 + }, + { + "date": "2023-05-14", + "value": 4.9 + }, + { + "date": "2023-07-12", + "value": 1.6 + }, + { + "date": "2023-09-16", + "value": 10.7 + }, + { + "date": "2023-11-25", + "value": 2.5 + }, + { + "date": "2024-01-28", + "value": 5.7 + }, + { + "date": "2024-03-11", + "value": 0.8 + }, + { + "date": "2024-05-17", + "value": 3.3 + }, + { + "date": "2024-07-27", + "value": 4.1 + }, + { + "date": "2024-09-10", + "value": 1.6 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 2.5 + }, + { + "date": "2025-03-22", + "value": 6.6 + }, + { + "date": "2025-06-03", + "value": 1.6 + }, + { + "date": "2025-08-08", + "value": 4.1 + }, + { + "date": "2025-09-04", + "value": 1.6 + }, + { + "date": "2025-09-10", + "value": 2.5 + }, + { + "date": "2025-09-16", + "value": 2.5 + }, + { + "date": "2025-09-22", + "value": 2.5 + }, + { + "date": "2025-10-05", + "value": 2.5 + }, + { + "date": "2025-10-11", + "value": 2.5 + }, + { + "date": "2025-10-17", + "value": 3.3 + }, + { + "date": "2025-10-23", + "value": 3.3 + }, + { + "date": "2025-11-06", + "value": 2.5 + }, + { + "date": "2025-11-12", + "value": 2.5 + }, + { + "date": "2025-11-18", + "value": 2.5 + }, + { + "date": "2025-11-24", + "value": 3.3 + }, + { + "date": "2025-12-04", + "value": 2.5 + }, + { + "date": "2025-12-10", + "value": 2.5 + }, + { + "date": "2025-12-16", + "value": 2.5 + }, + { + "date": "2025-12-22", + "value": 1.6 + }, + { + "date": "2026-01-05", + "value": 3.3 + }, + { + "date": "2026-01-11", + "value": 3.3 + }, + { + "date": "2026-01-17", + "value": 2.5 + }, + { + "date": "2026-01-23", + "value": 2.5 + }, + { + "date": "2026-02-06", + "value": 3.3 + }, + { + "date": "2026-02-12", + "value": 1.6 + }, + { + "date": "2026-02-18", + "value": 2.5 + }, + { + "date": "2026-02-24", + "value": 2.5 + }, + { + "date": "2026-03-04", + "value": 2.5 + }, + { + "date": "2026-03-10", + "value": 2.5 + }, + { + "date": "2026-03-16", + "value": 2.5 + }, + { + "date": "2026-03-22", + "value": 3.3 + }, + { + "date": "2026-04-05", + "value": 2.5 + }, + { + "date": "2026-04-11", + "value": 2.5 + }, + { + "date": "2026-04-17", + "value": 2.5 + }, + { + "date": "2026-04-23", + "value": 2.5 + }, + { + "date": "2026-05-06", + "value": 2.5 + }, + { + "date": "2026-05-12", + "value": 2.5 + }, + { + "date": "2026-05-18", + "value": 2.5 + }, + { + "date": "2026-05-24", + "value": 2.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-06", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2022-07", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-08", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-11", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2023-07", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-09", + "mean": 10.7, + "median": 10.7, + "p10": 10.7, + "p25": 10.7, + "p75": 10.7, + "p90": 10.7, + "n": 1 + }, + { + "month": "2023-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2024-03", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2024-05", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-09", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2025-06", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.3, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.3, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-01", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-02", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 2.8, + "median": 2.5, + "std": 1.8, + "min": 0.0, + "max": 10.7, + "p25": 2.5, + "p75": 3.3, + "p85": 3.3, + "p95": 4.9 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": null, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_highland_arabica.json new file mode 100644 index 00000000000..527fd049b67 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_highland_arabica.json @@ -0,0 +1,689 @@ +{ + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "durations": [ + 28.7, 50.8, 14.8, 72.2, 34.4, 45.1, 24.6, 59.0, 20.5, 39.4, 12.3, 77.9, + 106.6, 36.9, 31.2, 53.3, 18.0, 64.0, 4.1, 45.1, 32.8, 23.0, 69.7, 41.0, + 90.2, 26.2, 55.8, 36.9, 75.4, 16.4, 47.6, 28.7, 34.4, 61.5, 9.8, 39.4, 49.2, + 31.2, 40.2, 44.3, 27.9, 32.0, 34.4, 50.0, 33.6, 37.7, 40.2, 43.5, 29.5, + 33.6, 36.1, 39.4, 42.6, 29.5, 32.0, 35.3, 38.5, 41.8, 38.5, 41.0, 44.3, + 47.6, 32.0, 36.9, 40.2, 44.3, 27.9, 32.0, 45.9, 50.0, 33.6, 37.7, 40.2, + 45.9, 29.5, 33.6, 36.1, 39.4, 26.2, 29.5, 32.0, 35.3, 38.5 + ], + "observations": [ + { + "date": "2022-04-02", + "value": 28.7 + }, + { + "date": "2022-04-15", + "value": 50.8 + }, + { + "date": "2022-04-28", + "value": 14.8 + }, + { + "date": "2022-08-05", + "value": 72.2 + }, + { + "date": "2022-08-12", + "value": 34.4 + }, + { + "date": "2022-08-20", + "value": 45.1 + }, + { + "date": "2022-08-28", + "value": 24.6 + }, + { + "date": "2023-01-10", + "value": 59.0 + }, + { + "date": "2023-01-22", + "value": 20.5 + }, + { + "date": "2023-01-30", + "value": 39.4 + }, + { + "date": "2023-06-05", + "value": 12.3 + }, + { + "date": "2023-06-18", + "value": 77.9 + }, + { + "date": "2023-10-03", + "value": 106.6 + }, + { + "date": "2023-10-10", + "value": 36.9 + }, + { + "date": "2023-10-18", + "value": 31.2 + }, + { + "date": "2023-10-25", + "value": 53.3 + }, + { + "date": "2023-10-30", + "value": 18.0 + }, + { + "date": "2024-03-05", + "value": 64.0 + }, + { + "date": "2024-03-12", + "value": 4.1 + }, + { + "date": "2024-03-20", + "value": 45.1 + }, + { + "date": "2024-03-28", + "value": 32.8 + }, + { + "date": "2024-07-08", + "value": 23.0 + }, + { + "date": "2024-07-15", + "value": 69.7 + }, + { + "date": "2024-07-22", + "value": 41.0 + }, + { + "date": "2024-11-04", + "value": 90.2 + }, + { + "date": "2024-11-11", + "value": 26.2 + }, + { + "date": "2024-11-18", + "value": 55.8 + }, + { + "date": "2024-11-25", + "value": 36.9 + }, + { + "date": "2024-11-30", + "value": 75.4 + }, + { + "date": "2025-03-03", + "value": 16.4 + }, + { + "date": "2025-03-10", + "value": 47.6 + }, + { + "date": "2025-03-17", + "value": 28.7 + }, + { + "date": "2025-03-24", + "value": 34.4 + }, + { + "date": "2025-07-02", + "value": 61.5 + }, + { + "date": "2025-07-09", + "value": 9.8 + }, + { + "date": "2025-07-16", + "value": 39.4 + }, + { + "date": "2025-07-23", + "value": 49.2 + }, + { + "date": "2025-07-30", + "value": 31.2 + }, + { + "date": "2025-09-05", + "value": 40.2 + }, + { + "date": "2025-09-11", + "value": 44.3 + }, + { + "date": "2025-09-17", + "value": 27.9 + }, + { + "date": "2025-09-23", + "value": 32.0 + }, + { + "date": "2025-09-29", + "value": 34.4 + }, + { + "date": "2025-10-06", + "value": 50.0 + }, + { + "date": "2025-10-12", + "value": 33.6 + }, + { + "date": "2025-10-18", + "value": 37.7 + }, + { + "date": "2025-10-24", + "value": 40.2 + }, + { + "date": "2025-10-30", + "value": 43.5 + }, + { + "date": "2025-11-04", + "value": 29.5 + }, + { + "date": "2025-11-10", + "value": 33.6 + }, + { + "date": "2025-11-16", + "value": 36.1 + }, + { + "date": "2025-11-22", + "value": 39.4 + }, + { + "date": "2025-11-28", + "value": 42.6 + }, + { + "date": "2025-12-05", + "value": 29.5 + }, + { + "date": "2025-12-11", + "value": 32.0 + }, + { + "date": "2025-12-17", + "value": 35.3 + }, + { + "date": "2025-12-23", + "value": 38.5 + }, + { + "date": "2025-12-29", + "value": 41.8 + }, + { + "date": "2026-01-06", + "value": 38.5 + }, + { + "date": "2026-01-12", + "value": 41.0 + }, + { + "date": "2026-01-18", + "value": 44.3 + }, + { + "date": "2026-01-24", + "value": 47.6 + }, + { + "date": "2026-01-30", + "value": 32.0 + }, + { + "date": "2026-02-04", + "value": 36.9 + }, + { + "date": "2026-02-10", + "value": 40.2 + }, + { + "date": "2026-02-16", + "value": 44.3 + }, + { + "date": "2026-02-22", + "value": 27.9 + }, + { + "date": "2026-02-28", + "value": 32.0 + }, + { + "date": "2026-03-05", + "value": 45.9 + }, + { + "date": "2026-03-11", + "value": 50.0 + }, + { + "date": "2026-03-17", + "value": 33.6 + }, + { + "date": "2026-03-23", + "value": 37.7 + }, + { + "date": "2026-03-29", + "value": 40.2 + }, + { + "date": "2026-04-06", + "value": 45.9 + }, + { + "date": "2026-04-12", + "value": 29.5 + }, + { + "date": "2026-04-18", + "value": 33.6 + }, + { + "date": "2026-04-24", + "value": 36.1 + }, + { + "date": "2026-04-30", + "value": 39.4 + }, + { + "date": "2026-05-04", + "value": 26.2 + }, + { + "date": "2026-05-10", + "value": 29.5 + }, + { + "date": "2026-05-16", + "value": 32.0 + }, + { + "date": "2026-05-22", + "value": 35.3 + }, + { + "date": "2026-05-28", + "value": 38.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 31.4, + "median": 28.7, + "p10": 17.5, + "p25": 21.7, + "p75": 39.8, + "p90": 46.4, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 44.1, + "median": 39.8, + "p10": 27.6, + "p25": 32.0, + "p75": 51.9, + "p90": 64.0, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 39.6, + "median": 39.4, + "p10": 24.3, + "p25": 29.9, + "p75": 49.2, + "p90": 55.1, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 45.1, + "median": 45.1, + "p10": 18.9, + "p25": 28.7, + "p75": 61.5, + "p90": 71.3, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 49.2, + "median": 36.9, + "p10": 23.3, + "p25": 31.2, + "p75": 53.3, + "p90": 85.3, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 36.5, + "median": 38.9, + "p10": 12.7, + "p25": 25.7, + "p75": 49.9, + "p90": 58.3, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 44.5, + "median": 41.0, + "p10": 26.6, + "p25": 32.0, + "p75": 55.3, + "p90": 64.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 56.9, + "median": 55.8, + "p10": 30.5, + "p25": 36.9, + "p75": 75.4, + "p90": 84.3, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 31.8, + "median": 31.6, + "p10": 20.1, + "p25": 25.7, + "p75": 37.7, + "p90": 43.6, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 38.2, + "median": 39.4, + "p10": 18.4, + "p25": 31.2, + "p75": 49.2, + "p90": 56.6, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 35.8, + "median": 34.4, + "p10": 29.5, + "p25": 32.0, + "p75": 40.2, + "p90": 42.6, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 41.0, + "median": 40.2, + "p10": 35.3, + "p25": 37.7, + "p75": 43.5, + "p90": 47.4, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 36.2, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 35.4, + "median": 35.3, + "p10": 30.5, + "p25": 32.0, + "p75": 38.5, + "p90": 40.5, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 40.7, + "median": 41.0, + "p10": 34.6, + "p25": 38.5, + "p75": 44.3, + "p90": 46.2, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 36.2, + "median": 36.9, + "p10": 29.5, + "p25": 32.0, + "p75": 40.2, + "p90": 42.6, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 41.5, + "median": 40.2, + "p10": 35.3, + "p25": 37.7, + "p75": 45.9, + "p90": 48.4, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 36.9, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 39.4, + "p90": 43.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 32.3, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 35.3, + "p90": 37.2, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "stats": { + "n": 83, + "mean": 39.6, + "median": 37.7, + "std": 19.8, + "min": 4.1, + "max": 106.6, + "p25": 31.2, + "p75": 44.3, + "p85": 50.0, + "p95": 69.7 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": { + "unit_price": 2.624, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 38, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_lowland_robusta.json new file mode 100644 index 00000000000..4e38e79647d --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_lowland_robusta.json @@ -0,0 +1,563 @@ +{ + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "durations": [ + 23.0, 36.9, 9.8, 50.8, 27.1, 64.0, 16.4, 45.1, 6.6, 34.4, 53.3, 31.2, 12.3, + 59.0, 20.5, 39.4, 2.5, 69.7, 24.6, 45.1, 18.0, 32.8, 80.4, 14.8, 32.0, 33.6, + 36.9, 24.6, 27.9, 31.2, 33.6, 22.1, 24.6, 26.2, 31.2, 18.9, 22.1, 23.8, + 26.2, 23.0, 26.2, 27.9, 30.3, 32.8, 23.0, 25.4, 27.1, 29.5, 32.0, 29.5, + 32.0, 33.6, 36.9, 24.6, 28.7, 31.2, 33.6, 22.1, 24.6, 27.9, 31.2, 18.9, + 22.1, 23.8, 35.3, 23.0, 26.2, 27.9, 30.3 + ], + "observations": [ + { + "date": "2022-05-02", + "value": 23.0 + }, + { + "date": "2022-05-10", + "value": 36.9 + }, + { + "date": "2022-05-18", + "value": 9.8 + }, + { + "date": "2022-05-25", + "value": 50.8 + }, + { + "date": "2023-02-06", + "value": 27.1 + }, + { + "date": "2023-02-14", + "value": 64.0 + }, + { + "date": "2023-02-22", + "value": 16.4 + }, + { + "date": "2023-02-28", + "value": 45.1 + }, + { + "date": "2023-09-05", + "value": 6.6 + }, + { + "date": "2023-09-15", + "value": 34.4 + }, + { + "date": "2023-09-25", + "value": 53.3 + }, + { + "date": "2024-04-03", + "value": 31.2 + }, + { + "date": "2024-04-10", + "value": 12.3 + }, + { + "date": "2024-04-17", + "value": 59.0 + }, + { + "date": "2024-04-24", + "value": 20.5 + }, + { + "date": "2024-10-02", + "value": 39.4 + }, + { + "date": "2024-10-09", + "value": 2.5 + }, + { + "date": "2024-10-16", + "value": 69.7 + }, + { + "date": "2024-10-23", + "value": 24.6 + }, + { + "date": "2024-10-30", + "value": 45.1 + }, + { + "date": "2025-04-07", + "value": 18.0 + }, + { + "date": "2025-04-14", + "value": 32.8 + }, + { + "date": "2025-04-21", + "value": 80.4 + }, + { + "date": "2025-04-28", + "value": 14.8 + }, + { + "date": "2025-09-04", + "value": 32.0 + }, + { + "date": "2025-09-10", + "value": 33.6 + }, + { + "date": "2025-09-16", + "value": 36.9 + }, + { + "date": "2025-09-22", + "value": 24.6 + }, + { + "date": "2025-09-28", + "value": 27.9 + }, + { + "date": "2025-10-05", + "value": 31.2 + }, + { + "date": "2025-10-11", + "value": 33.6 + }, + { + "date": "2025-10-17", + "value": 22.1 + }, + { + "date": "2025-10-23", + "value": 24.6 + }, + { + "date": "2025-10-29", + "value": 26.2 + }, + { + "date": "2025-11-06", + "value": 31.2 + }, + { + "date": "2025-11-12", + "value": 18.9 + }, + { + "date": "2025-11-18", + "value": 22.1 + }, + { + "date": "2025-11-24", + "value": 23.8 + }, + { + "date": "2025-11-30", + "value": 26.2 + }, + { + "date": "2025-12-04", + "value": 23.0 + }, + { + "date": "2025-12-10", + "value": 26.2 + }, + { + "date": "2025-12-16", + "value": 27.9 + }, + { + "date": "2025-12-22", + "value": 30.3 + }, + { + "date": "2025-12-28", + "value": 32.8 + }, + { + "date": "2026-01-05", + "value": 23.0 + }, + { + "date": "2026-01-11", + "value": 25.4 + }, + { + "date": "2026-01-17", + "value": 27.1 + }, + { + "date": "2026-01-23", + "value": 29.5 + }, + { + "date": "2026-01-29", + "value": 32.0 + }, + { + "date": "2026-02-06", + "value": 29.5 + }, + { + "date": "2026-02-12", + "value": 32.0 + }, + { + "date": "2026-02-18", + "value": 33.6 + }, + { + "date": "2026-02-24", + "value": 36.9 + }, + { + "date": "2026-02-30", + "value": 24.6 + }, + { + "date": "2026-03-04", + "value": 28.7 + }, + { + "date": "2026-03-10", + "value": 31.2 + }, + { + "date": "2026-03-16", + "value": 33.6 + }, + { + "date": "2026-03-22", + "value": 22.1 + }, + { + "date": "2026-03-28", + "value": 24.6 + }, + { + "date": "2026-04-05", + "value": 27.9 + }, + { + "date": "2026-04-11", + "value": 31.2 + }, + { + "date": "2026-04-17", + "value": 18.9 + }, + { + "date": "2026-04-23", + "value": 22.1 + }, + { + "date": "2026-04-29", + "value": 23.8 + }, + { + "date": "2026-05-06", + "value": 35.3 + }, + { + "date": "2026-05-12", + "value": 23.0 + }, + { + "date": "2026-05-18", + "value": 26.2 + }, + { + "date": "2026-05-24", + "value": 27.9 + }, + { + "date": "2026-05-30", + "value": 30.3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 30.2, + "median": 29.9, + "p10": 13.8, + "p25": 19.7, + "p75": 40.4, + "p90": 46.7, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 38.1, + "median": 36.1, + "p10": 19.6, + "p25": 24.4, + "p75": 49.9, + "p90": 58.3, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 31.4, + "median": 34.4, + "p10": 12.1, + "p25": 20.5, + "p75": 43.9, + "p90": 49.5, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 30.7, + "median": 25.8, + "p10": 14.8, + "p25": 18.4, + "p75": 38.1, + "p90": 50.7, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 36.2, + "median": 39.4, + "p10": 11.3, + "p25": 24.6, + "p75": 45.1, + "p90": 59.9, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 36.5, + "median": 25.4, + "p10": 15.7, + "p25": 17.2, + "p75": 44.7, + "p90": 66.1, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 31.0, + "median": 32.0, + "p10": 25.9, + "p25": 27.9, + "p75": 33.6, + "p90": 35.6, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 27.6, + "median": 26.2, + "p10": 23.1, + "p25": 24.6, + "p75": 31.2, + "p90": 32.6, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 24.4, + "median": 23.8, + "p10": 20.2, + "p25": 22.1, + "p75": 26.2, + "p90": 29.2, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 28.0, + "median": 27.9, + "p10": 24.3, + "p25": 26.2, + "p75": 30.3, + "p90": 31.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 27.4, + "median": 27.1, + "p10": 23.9, + "p25": 25.4, + "p75": 29.5, + "p90": 31.0, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 31.3, + "median": 32.0, + "p10": 26.6, + "p25": 29.5, + "p75": 33.6, + "p90": 35.6, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 28.0, + "median": 28.7, + "p10": 23.1, + "p25": 24.6, + "p75": 31.2, + "p90": 32.6, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 24.8, + "median": 23.8, + "p10": 20.2, + "p25": 22.1, + "p75": 27.9, + "p90": 29.8, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 28.5, + "median": 27.9, + "p10": 24.3, + "p25": 26.2, + "p75": 30.3, + "p90": 33.3, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "stats": { + "n": 69, + "mean": 30.0, + "median": 27.9, + "std": 15.8, + "min": 2.5, + "max": 80.4, + "p25": 23.0, + "p75": 33.6, + "p85": 36.9, + "p95": 53.3 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "annotations": [], + "cost": { + "unit_price": 1.476, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 42, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_washed_bourbon.json new file mode 100644 index 00000000000..6cc30100aba --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/raw_dwell_washed_bourbon.json @@ -0,0 +1,567 @@ +{ + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "durations": [ + 32.8, 18.0, 55.8, 3.3, 45.1, 94.3, 24.6, 50.8, 14.8, 69.7, 28.7, 59.0, 8.2, + 39.4, 77.9, 23.0, 42.6, 12.3, 64.0, 34.4, 6.6, 53.3, 27.1, 82.0, 16.4, 33.6, + 36.9, 39.4, 42.6, 27.9, 32.8, 36.1, 39.4, 24.6, 27.9, 41.0, 44.3, 29.5, + 33.6, 36.1, 41.0, 26.2, 29.5, 32.0, 35.3, 23.0, 26.2, 28.7, 31.2, 34.4, + 32.0, 33.6, 36.9, 39.4, 42.6, 30.3, 32.8, 36.1, 39.4, 24.6, 38.5, 41.0, + 44.3, 29.5, 33.6, 37.7, 41.0, 26.2, 29.5, 32.0 + ], + "observations": [ + { + "date": "2022-06-05", + "value": 32.8 + }, + { + "date": "2022-06-15", + "value": 18.0 + }, + { + "date": "2022-06-25", + "value": 55.8 + }, + { + "date": "2023-03-08", + "value": 3.3 + }, + { + "date": "2023-03-15", + "value": 45.1 + }, + { + "date": "2023-03-22", + "value": 94.3 + }, + { + "date": "2023-03-29", + "value": 24.6 + }, + { + "date": "2023-11-06", + "value": 50.8 + }, + { + "date": "2023-11-13", + "value": 14.8 + }, + { + "date": "2023-11-20", + "value": 69.7 + }, + { + "date": "2024-06-03", + "value": 28.7 + }, + { + "date": "2024-06-10", + "value": 59.0 + }, + { + "date": "2024-06-17", + "value": 8.2 + }, + { + "date": "2024-06-24", + "value": 39.4 + }, + { + "date": "2024-06-30", + "value": 77.9 + }, + { + "date": "2025-01-07", + "value": 23.0 + }, + { + "date": "2025-01-14", + "value": 42.6 + }, + { + "date": "2025-01-21", + "value": 12.3 + }, + { + "date": "2025-01-28", + "value": 64.0 + }, + { + "date": "2025-08-04", + "value": 34.4 + }, + { + "date": "2025-08-08", + "value": 6.6 + }, + { + "date": "2025-08-12", + "value": 53.3 + }, + { + "date": "2025-08-16", + "value": 27.1 + }, + { + "date": "2025-08-20", + "value": 82.0 + }, + { + "date": "2025-08-24", + "value": 16.4 + }, + { + "date": "2025-09-06", + "value": 33.6 + }, + { + "date": "2025-09-12", + "value": 36.9 + }, + { + "date": "2025-09-18", + "value": 39.4 + }, + { + "date": "2025-09-24", + "value": 42.6 + }, + { + "date": "2025-09-30", + "value": 27.9 + }, + { + "date": "2025-10-04", + "value": 32.8 + }, + { + "date": "2025-10-10", + "value": 36.1 + }, + { + "date": "2025-10-16", + "value": 39.4 + }, + { + "date": "2025-10-22", + "value": 24.6 + }, + { + "date": "2025-10-28", + "value": 27.9 + }, + { + "date": "2025-11-05", + "value": 41.0 + }, + { + "date": "2025-11-11", + "value": 44.3 + }, + { + "date": "2025-11-17", + "value": 29.5 + }, + { + "date": "2025-11-23", + "value": 33.6 + }, + { + "date": "2025-11-29", + "value": 36.1 + }, + { + "date": "2025-12-06", + "value": 41.0 + }, + { + "date": "2025-12-12", + "value": 26.2 + }, + { + "date": "2025-12-18", + "value": 29.5 + }, + { + "date": "2025-12-24", + "value": 32.0 + }, + { + "date": "2025-12-30", + "value": 35.3 + }, + { + "date": "2026-01-04", + "value": 23.0 + }, + { + "date": "2026-01-10", + "value": 26.2 + }, + { + "date": "2026-01-16", + "value": 28.7 + }, + { + "date": "2026-01-22", + "value": 31.2 + }, + { + "date": "2026-01-28", + "value": 34.4 + }, + { + "date": "2026-02-05", + "value": 32.0 + }, + { + "date": "2026-02-11", + "value": 33.6 + }, + { + "date": "2026-02-17", + "value": 36.9 + }, + { + "date": "2026-02-23", + "value": 39.4 + }, + { + "date": "2026-02-29", + "value": 42.6 + }, + { + "date": "2026-03-06", + "value": 30.3 + }, + { + "date": "2026-03-12", + "value": 32.8 + }, + { + "date": "2026-03-18", + "value": 36.1 + }, + { + "date": "2026-03-24", + "value": 39.4 + }, + { + "date": "2026-03-30", + "value": 24.6 + }, + { + "date": "2026-04-04", + "value": 38.5 + }, + { + "date": "2026-04-10", + "value": 41.0 + }, + { + "date": "2026-04-16", + "value": 44.3 + }, + { + "date": "2026-04-22", + "value": 29.5 + }, + { + "date": "2026-04-28", + "value": 33.6 + }, + { + "date": "2026-05-05", + "value": 37.7 + }, + { + "date": "2026-05-11", + "value": 41.0 + }, + { + "date": "2026-05-17", + "value": 26.2 + }, + { + "date": "2026-05-23", + "value": 29.5 + }, + { + "date": "2026-05-29", + "value": 32.0 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 35.5, + "median": 32.8, + "p10": 21.0, + "p25": 25.4, + "p75": 44.3, + "p90": 51.2, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 41.8, + "median": 34.9, + "p10": 9.7, + "p25": 19.3, + "p75": 57.4, + "p90": 79.5, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 45.1, + "median": 50.8, + "p10": 22.0, + "p25": 32.8, + "p75": 60.3, + "p90": 65.9, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 42.6, + "median": 39.4, + "p10": 16.4, + "p25": 28.7, + "p75": 59.0, + "p90": 70.4, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 35.5, + "median": 32.8, + "p10": 15.5, + "p25": 20.3, + "p75": 48.0, + "p90": 57.6, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 36.7, + "median": 30.7, + "p10": 11.5, + "p25": 19.1, + "p75": 48.6, + "p90": 67.6, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 36.1, + "median": 36.9, + "p10": 30.2, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 32.1, + "median": 32.8, + "p10": 25.9, + "p25": 27.9, + "p75": 36.1, + "p90": 38.0, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 36.9, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 41.0, + "p90": 43.0, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 32.8, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 35.3, + "p90": 38.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 28.7, + "median": 28.7, + "p10": 24.3, + "p25": 26.2, + "p75": 31.2, + "p90": 33.1, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 36.9, + "median": 36.9, + "p10": 32.6, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 32.6, + "median": 32.8, + "p10": 26.9, + "p25": 30.3, + "p75": 36.1, + "p90": 38.0, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 37.4, + "median": 38.5, + "p10": 31.2, + "p25": 33.6, + "p75": 41.0, + "p90": 43.0, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 33.3, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 37.7, + "p90": 39.7, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "stats": { + "n": 70, + "mean": 36.0, + "median": 33.6, + "std": 19.1, + "min": 3.3, + "max": 94.3, + "p25": 27.9, + "p75": 41.0, + "p85": 44.3, + "p95": 64.0 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "annotations": [], + "cost": { + "unit_price": 4.51, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 25, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/transit_pla_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/transit_pla_hub1.json new file mode 100644 index 00000000000..b98d937052b --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/riverside-decaf/steps/transit_pla_hub1.json @@ -0,0 +1,437 @@ +{ + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "durations": [ + 23.0, 28.7, 18.0, 34.4, 24.6, 45.1, 20.5, 31.2, 12.3, 26.2, 23.0, 36.9, + 24.6, 18.0, 29.5, 31.2, 32.0, 21.3, 29.5, 18.9, 21.3, 22.1, 25.4, 27.1, + 22.1, 23.8, 26.2, 21.3, 23.8, 25.4, 27.1, 29.5, 32.0, 27.1, 29.5, 18.9, + 32.8, 22.1, 25.4, 19.7, 22.1, 23.8 + ], + "observations": [ + { + "date": "2022-07-20", + "value": 23.0 + }, + { + "date": "2022-11-30", + "value": 28.7 + }, + { + "date": "2023-03-15", + "value": 18.0 + }, + { + "date": "2023-07-10", + "value": 34.4 + }, + { + "date": "2023-10-25", + "value": 24.6 + }, + { + "date": "2024-02-08", + "value": 45.1 + }, + { + "date": "2024-05-20", + "value": 20.5 + }, + { + "date": "2024-08-12", + "value": 31.2 + }, + { + "date": "2024-11-05", + "value": 12.3 + }, + { + "date": "2025-01-22", + "value": 26.2 + }, + { + "date": "2025-04-10", + "value": 23.0 + }, + { + "date": "2025-06-18", + "value": 36.9 + }, + { + "date": "2025-07-15", + "value": 24.6 + }, + { + "date": "2025-08-05", + "value": 18.0 + }, + { + "date": "2025-09-05", + "value": 29.5 + }, + { + "date": "2025-09-10", + "value": 31.2 + }, + { + "date": "2025-09-11", + "value": 32.0 + }, + { + "date": "2025-09-17", + "value": 21.3 + }, + { + "date": "2025-10-06", + "value": 29.5 + }, + { + "date": "2025-10-12", + "value": 18.9 + }, + { + "date": "2025-10-18", + "value": 21.3 + }, + { + "date": "2025-11-04", + "value": 22.1 + }, + { + "date": "2025-11-10", + "value": 25.4 + }, + { + "date": "2025-11-16", + "value": 27.1 + }, + { + "date": "2025-12-05", + "value": 22.1 + }, + { + "date": "2025-12-11", + "value": 23.8 + }, + { + "date": "2025-12-17", + "value": 26.2 + }, + { + "date": "2026-01-06", + "value": 21.3 + }, + { + "date": "2026-01-12", + "value": 23.8 + }, + { + "date": "2026-01-18", + "value": 25.4 + }, + { + "date": "2026-02-04", + "value": 27.1 + }, + { + "date": "2026-02-10", + "value": 29.5 + }, + { + "date": "2026-02-16", + "value": 32.0 + }, + { + "date": "2026-03-05", + "value": 27.1 + }, + { + "date": "2026-03-11", + "value": 29.5 + }, + { + "date": "2026-03-17", + "value": 18.9 + }, + { + "date": "2026-04-06", + "value": 32.8 + }, + { + "date": "2026-04-12", + "value": 22.1 + }, + { + "date": "2026-04-18", + "value": 25.4 + }, + { + "date": "2026-05-04", + "value": 19.7 + }, + { + "date": "2026-05-10", + "value": 22.1 + }, + { + "date": "2026-05-16", + "value": 23.8 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2023-03", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1 + }, + { + "month": "2023-10", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2024-02", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2024-05", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-11", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 26.2, + "median": 26.2, + "p10": 26.2, + "p25": 26.2, + "p75": 26.2, + "p90": 26.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 36.9, + "median": 36.9, + "p10": 36.9, + "p25": 36.9, + "p75": 36.9, + "p90": 36.9, + "n": 1 + }, + { + "month": "2025-07", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2025-08", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 28.5, + "median": 30.3, + "p10": 23.8, + "p25": 27.5, + "p75": 31.4, + "p90": 31.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 23.2, + "median": 21.3, + "p10": 19.4, + "p25": 20.1, + "p75": 25.4, + "p90": 27.9, + "n": 3 + }, + { + "month": "2025-11", + "mean": 24.8, + "median": 25.4, + "p10": 22.8, + "p25": 23.8, + "p75": 26.2, + "p90": 26.7, + "n": 3 + }, + { + "month": "2025-12", + "mean": 24.0, + "median": 23.8, + "p10": 22.5, + "p25": 23.0, + "p75": 25.0, + "p90": 25.7, + "n": 3 + }, + { + "month": "2026-01", + "mean": 23.5, + "median": 23.8, + "p10": 21.8, + "p25": 22.5, + "p75": 24.6, + "p90": 25.1, + "n": 3 + }, + { + "month": "2026-02", + "mean": 29.5, + "median": 29.5, + "p10": 27.6, + "p25": 28.3, + "p75": 30.7, + "p90": 31.5, + "n": 3 + }, + { + "month": "2026-03", + "mean": 25.2, + "median": 27.1, + "p10": 20.5, + "p25": 23.0, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-04", + "mean": 26.8, + "median": 25.4, + "p10": 22.8, + "p25": 23.8, + "p75": 29.1, + "p90": 31.3, + "n": 3 + }, + { + "month": "2026-05", + "mean": 21.9, + "median": 22.1, + "p10": 20.2, + "p25": 20.9, + "p75": 23.0, + "p90": 23.5, + "n": 3 + } + ], + "stats": { + "n": 42, + "mean": 25.7, + "median": 24.6, + "std": 7.1, + "min": 12.3, + "max": 45.1, + "p25": 22.1, + "p75": 29.5, + "p85": 31.2, + "p95": 32.8 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 15, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/site/harbor-roastery/summary.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/site/harbor-roastery/summary.json new file mode 100644 index 00000000000..c249c987fc8 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/site/harbor-roastery/summary.json @@ -0,0 +1,29435 @@ +{ + "schema_version": "1.0", + "site_id": "harbor-roastery", + "generated_at": "2026-06-17T16:40:29Z", + "products": [ + { + "id": "harbor-dark-roast", + "name": "Harbor Dark Roast", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 40.2, + "median": 40.0, + "std": 13.3, + "min": 8, + "max": 105, + "p25": 35.0, + "p75": 45.0, + "p85": 48.0, + "p95": 55.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 55 + }, + { + "date": "2022-06-10", + "value": 42 + }, + { + "date": "2022-09-22", + "value": 8 + }, + { + "date": "2022-12-05", + "value": 63 + }, + { + "date": "2023-02-14", + "value": 38 + }, + { + "date": "2023-05-30", + "value": 22 + }, + { + "date": "2023-08-17", + "value": 71 + }, + { + "date": "2023-11-02", + "value": 30 + }, + { + "date": "2024-01-25", + "value": 45 + }, + { + "date": "2024-04-11", + "value": 18 + }, + { + "date": "2024-07-09", + "value": 105 + }, + { + "date": "2024-10-03", + "value": 35 + }, + { + "date": "2025-01-20", + "value": 12 + }, + { + "date": "2025-04-08", + "value": 48 + }, + { + "date": "2025-09-05", + "value": 39 + }, + { + "date": "2025-09-11", + "value": 41 + }, + { + "date": "2025-09-17", + "value": 44 + }, + { + "date": "2025-09-23", + "value": 48 + }, + { + "date": "2025-09-29", + "value": 51 + }, + { + "date": "2025-10-06", + "value": 37 + }, + { + "date": "2025-10-12", + "value": 40 + }, + { + "date": "2025-10-18", + "value": 44 + }, + { + "date": "2025-10-24", + "value": 47 + }, + { + "date": "2025-10-30", + "value": 31 + }, + { + "date": "2025-11-04", + "value": 36 + }, + { + "date": "2025-11-10", + "value": 40 + }, + { + "date": "2025-11-16", + "value": 43 + }, + { + "date": "2025-11-22", + "value": 27 + }, + { + "date": "2025-11-28", + "value": 31 + }, + { + "date": "2025-12-05", + "value": 46 + }, + { + "date": "2025-12-11", + "value": 49 + }, + { + "date": "2025-12-17", + "value": 33 + }, + { + "date": "2025-12-23", + "value": 37 + }, + { + "date": "2025-12-29", + "value": 39 + }, + { + "date": "2026-01-06", + "value": 45 + }, + { + "date": "2026-01-12", + "value": 29 + }, + { + "date": "2026-01-18", + "value": 33 + }, + { + "date": "2026-01-24", + "value": 35 + }, + { + "date": "2026-01-30", + "value": 38 + }, + { + "date": "2026-02-04", + "value": 35 + }, + { + "date": "2026-02-10", + "value": 39 + }, + { + "date": "2026-02-16", + "value": 41 + }, + { + "date": "2026-02-22", + "value": 44 + }, + { + "date": "2026-02-28", + "value": 48 + }, + { + "date": "2026-03-05", + "value": 35 + }, + { + "date": "2026-03-11", + "value": 37 + }, + { + "date": "2026-03-17", + "value": 40 + }, + { + "date": "2026-03-23", + "value": 44 + }, + { + "date": "2026-03-29", + "value": 47 + }, + { + "date": "2026-04-06", + "value": 33 + }, + { + "date": "2026-04-12", + "value": 36 + }, + { + "date": "2026-04-18", + "value": 40 + }, + { + "date": "2026-04-24", + "value": 43 + }, + { + "date": "2026-04-30", + "value": 27 + }, + { + "date": "2026-05-04", + "value": 42 + }, + { + "date": "2026-05-10", + "value": 46 + }, + { + "date": "2026-05-16", + "value": 49 + }, + { + "date": "2026-05-22", + "value": 33 + }, + { + "date": "2026-05-28", + "value": 37 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1 + }, + { + "month": "2022-09", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2022-12", + "mean": 63.0, + "median": 63.0, + "p10": 63.0, + "p25": 63.0, + "p75": 63.0, + "p90": 63.0, + "n": 1 + }, + { + "month": "2023-02", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 71.0, + "median": 71.0, + "p10": 71.0, + "p25": 71.0, + "p75": 71.0, + "p90": 71.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 45.0, + "median": 45.0, + "p10": 45.0, + "p25": 45.0, + "p75": 45.0, + "p90": 45.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 105.0, + "median": 105.0, + "p10": 105.0, + "p25": 105.0, + "p75": 105.0, + "p90": 105.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 44.6, + "median": 44.0, + "p10": 39.8, + "p25": 41.0, + "p75": 48.0, + "p90": 49.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 39.8, + "median": 40.0, + "p10": 33.4, + "p25": 37.0, + "p75": 44.0, + "p90": 45.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 35.4, + "median": 36.0, + "p10": 28.6, + "p25": 31.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 40.8, + "median": 39.0, + "p10": 34.6, + "p25": 37.0, + "p75": 46.0, + "p90": 47.8, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.0, + "median": 35.0, + "p10": 30.6, + "p25": 33.0, + "p75": 38.0, + "p90": 42.2, + "n": 5 + }, + { + "month": "2026-02", + "mean": 41.4, + "median": 41.0, + "p10": 36.6, + "p25": 39.0, + "p75": 44.0, + "p90": 46.4, + "n": 5 + }, + { + "month": "2026-03", + "mean": 40.6, + "median": 40.0, + "p10": 35.8, + "p25": 37.0, + "p75": 44.0, + "p90": 45.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 35.8, + "median": 36.0, + "p10": 29.4, + "p25": 33.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2026-05", + "mean": 41.4, + "median": 42.0, + "p10": 34.6, + "p25": 37.0, + "p75": 46.0, + "p90": 47.8, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 33.4, + "median": 33.0, + "std": 11.4, + "min": 5, + "max": 82, + "p25": 28.0, + "p75": 38.0, + "p85": 40.7, + "p95": 51.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 32 + }, + { + "date": "2022-04-19", + "value": 48 + }, + { + "date": "2022-07-11", + "value": 5 + }, + { + "date": "2022-09-28", + "value": 67 + }, + { + "date": "2022-12-15", + "value": 25 + }, + { + "date": "2023-03-07", + "value": 41 + }, + { + "date": "2023-05-22", + "value": 15 + }, + { + "date": "2023-08-09", + "value": 82 + }, + { + "date": "2023-10-30", + "value": 38 + }, + { + "date": "2024-01-16", + "value": 20 + }, + { + "date": "2024-03-25", + "value": 52 + }, + { + "date": "2024-06-12", + "value": 10 + }, + { + "date": "2024-08-28", + "value": 44 + }, + { + "date": "2024-11-14", + "value": 28 + }, + { + "date": "2025-01-06", + "value": 35 + }, + { + "date": "2025-03-18", + "value": 18 + }, + { + "date": "2025-05-29", + "value": 55 + }, + { + "date": "2025-08-12", + "value": 26 + }, + { + "date": "2025-09-04", + "value": 26 + }, + { + "date": "2025-09-10", + "value": 29 + }, + { + "date": "2025-09-16", + "value": 31 + }, + { + "date": "2025-09-22", + "value": 34 + }, + { + "date": "2025-09-28", + "value": 37 + }, + { + "date": "2025-10-05", + "value": 26 + }, + { + "date": "2025-10-11", + "value": 28 + }, + { + "date": "2025-10-17", + "value": 31 + }, + { + "date": "2025-10-23", + "value": 33 + }, + { + "date": "2025-10-29", + "value": 36 + }, + { + "date": "2025-11-06", + "value": 33 + }, + { + "date": "2025-11-12", + "value": 36 + }, + { + "date": "2025-11-18", + "value": 38 + }, + { + "date": "2025-11-24", + "value": 42 + }, + { + "date": "2025-11-30", + "value": 28 + }, + { + "date": "2025-12-04", + "value": 32 + }, + { + "date": "2025-12-10", + "value": 35 + }, + { + "date": "2025-12-16", + "value": 38 + }, + { + "date": "2025-12-22", + "value": 24 + }, + { + "date": "2025-12-28", + "value": 28 + }, + { + "date": "2026-01-05", + "value": 40 + }, + { + "date": "2026-01-11", + "value": 43 + }, + { + "date": "2026-01-17", + "value": 29 + }, + { + "date": "2026-01-23", + "value": 33 + }, + { + "date": "2026-01-29", + "value": 35 + }, + { + "date": "2026-02-06", + "value": 40 + }, + { + "date": "2026-02-12", + "value": 26 + }, + { + "date": "2026-02-18", + "value": 29 + }, + { + "date": "2026-02-24", + "value": 31 + }, + { + "date": "2026-02-30", + "value": 34 + }, + { + "date": "2026-03-04", + "value": 22 + }, + { + "date": "2026-03-10", + "value": 26 + }, + { + "date": "2026-03-16", + "value": 28 + }, + { + "date": "2026-03-22", + "value": 31 + }, + { + "date": "2026-03-28", + "value": 33 + }, + { + "date": "2026-04-05", + "value": 31 + }, + { + "date": "2026-04-11", + "value": 33 + }, + { + "date": "2026-04-17", + "value": 36 + }, + { + "date": "2026-04-23", + "value": 38 + }, + { + "date": "2026-04-29", + "value": 42 + }, + { + "date": "2026-05-06", + "value": 30 + }, + { + "date": "2026-05-12", + "value": 32 + }, + { + "date": "2026-05-18", + "value": 35 + }, + { + "date": "2026-05-24", + "value": 38 + }, + { + "date": "2026-05-30", + "value": 24 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 32.0, + "median": 32.0, + "p10": 32.0, + "p25": 32.0, + "p75": 32.0, + "p90": 32.0, + "n": 1 + }, + { + "month": "2022-04", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-09", + "mean": 67.0, + "median": 67.0, + "p10": 67.0, + "p25": 67.0, + "p75": 67.0, + "p90": 67.0, + "n": 1 + }, + { + "month": "2022-12", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 41.0, + "median": 41.0, + "p10": 41.0, + "p25": 41.0, + "p75": 41.0, + "p90": 41.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 82.0, + "median": 82.0, + "p10": 82.0, + "p25": 82.0, + "p75": 82.0, + "p90": 82.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 20.0, + "median": 20.0, + "p10": 20.0, + "p25": 20.0, + "p75": 20.0, + "p90": 20.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 52.0, + "median": 52.0, + "p10": 52.0, + "p25": 52.0, + "p75": 52.0, + "p90": 52.0, + "n": 1 + }, + { + "month": "2024-06", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1 + }, + { + "month": "2024-08", + "mean": 44.0, + "median": 44.0, + "p10": 44.0, + "p25": 44.0, + "p75": 44.0, + "p90": 44.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 31.4, + "median": 31.0, + "p10": 27.2, + "p25": 29.0, + "p75": 34.0, + "p90": 35.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 30.8, + "median": 31.0, + "p10": 26.8, + "p25": 28.0, + "p75": 33.0, + "p90": 34.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 35.4, + "median": 36.0, + "p10": 30.0, + "p25": 33.0, + "p75": 38.0, + "p90": 40.4, + "n": 5 + }, + { + "month": "2025-12", + "mean": 31.4, + "median": 32.0, + "p10": 25.6, + "p25": 28.0, + "p75": 35.0, + "p90": 36.8, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.0, + "median": 35.0, + "p10": 30.6, + "p25": 33.0, + "p75": 40.0, + "p90": 41.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 32.0, + "median": 31.0, + "p10": 27.2, + "p25": 29.0, + "p75": 34.0, + "p90": 37.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 28.0, + "median": 28.0, + "p10": 23.6, + "p25": 26.0, + "p75": 31.0, + "p90": 32.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 36.0, + "median": 36.0, + "p10": 31.8, + "p25": 33.0, + "p75": 38.0, + "p90": 40.4, + "n": 5 + }, + { + "month": "2026-05", + "mean": 31.8, + "median": 32.0, + "p10": 26.4, + "p25": 30.0, + "p75": 35.0, + "p90": 36.8, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 26.1, + "median": 25.0, + "std": 8.0, + "min": 7, + "max": 62, + "p25": 22.5, + "p75": 29.0, + "p85": 30.0, + "p95": 36.5 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 35 + }, + { + "date": "2022-10-18", + "value": 16 + }, + { + "date": "2023-01-24", + "value": 62 + }, + { + "date": "2023-06-15", + "value": 7 + }, + { + "date": "2023-09-28", + "value": 40 + }, + { + "date": "2024-02-12", + "value": 25 + }, + { + "date": "2024-05-07", + "value": 48 + }, + { + "date": "2024-09-19", + "value": 12 + }, + { + "date": "2025-02-04", + "value": 30 + }, + { + "date": "2025-06-10", + "value": 14 + }, + { + "date": "2025-09-06", + "value": 30 + }, + { + "date": "2025-09-12", + "value": 19 + }, + { + "date": "2025-09-18", + "value": 22 + }, + { + "date": "2025-09-24", + "value": 23 + }, + { + "date": "2025-09-30", + "value": 25 + }, + { + "date": "2025-10-04", + "value": 23 + }, + { + "date": "2025-10-10", + "value": 25 + }, + { + "date": "2025-10-16", + "value": 27 + }, + { + "date": "2025-10-22", + "value": 29 + }, + { + "date": "2025-10-28", + "value": 31 + }, + { + "date": "2025-11-05", + "value": 23 + }, + { + "date": "2025-11-11", + "value": 25 + }, + { + "date": "2025-11-17", + "value": 27 + }, + { + "date": "2025-11-23", + "value": 29 + }, + { + "date": "2025-11-29", + "value": 31 + }, + { + "date": "2025-12-06", + "value": 22 + }, + { + "date": "2025-12-12", + "value": 24 + }, + { + "date": "2025-12-18", + "value": 26 + }, + { + "date": "2025-12-24", + "value": 28 + }, + { + "date": "2025-12-30", + "value": 18 + }, + { + "date": "2026-01-04", + "value": 28 + }, + { + "date": "2026-01-10", + "value": 30 + }, + { + "date": "2026-01-16", + "value": 32 + }, + { + "date": "2026-01-22", + "value": 22 + }, + { + "date": "2026-01-28", + "value": 24 + }, + { + "date": "2026-02-05", + "value": 27 + }, + { + "date": "2026-02-11", + "value": 30 + }, + { + "date": "2026-02-17", + "value": 19 + }, + { + "date": "2026-02-23", + "value": 22 + }, + { + "date": "2026-02-29", + "value": 23 + }, + { + "date": "2026-03-06", + "value": 34 + }, + { + "date": "2026-03-12", + "value": 23 + }, + { + "date": "2026-03-18", + "value": 25 + }, + { + "date": "2026-03-24", + "value": 27 + }, + { + "date": "2026-03-30", + "value": 29 + }, + { + "date": "2026-04-04", + "value": 20 + }, + { + "date": "2026-04-10", + "value": 23 + }, + { + "date": "2026-04-16", + "value": 25 + }, + { + "date": "2026-04-22", + "value": 27 + }, + { + "date": "2026-04-28", + "value": 29 + }, + { + "date": "2026-05-05", + "value": 20 + }, + { + "date": "2026-05-11", + "value": 22 + }, + { + "date": "2026-05-17", + "value": 24 + }, + { + "date": "2026-05-23", + "value": 26 + }, + { + "date": "2026-05-29", + "value": 28 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 16.0, + "median": 16.0, + "p10": 16.0, + "p25": 16.0, + "p75": 16.0, + "p90": 16.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 62.0, + "median": 62.0, + "p10": 62.0, + "p25": 62.0, + "p75": 62.0, + "p90": 62.0, + "n": 1 + }, + { + "month": "2023-06", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 40.0, + "median": 40.0, + "p10": 40.0, + "p25": 40.0, + "p75": 40.0, + "p90": 40.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 48.0, + "median": 48.0, + "p10": 48.0, + "p25": 48.0, + "p75": 48.0, + "p90": 48.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2025-02", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 14.0, + "median": 14.0, + "p10": 14.0, + "p25": 14.0, + "p75": 14.0, + "p90": 14.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 23.8, + "median": 23.0, + "p10": 20.2, + "p25": 22.0, + "p75": 25.0, + "p90": 28.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 27.0, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 30.2, + "n": 5 + }, + { + "month": "2025-11", + "mean": 27.0, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 30.2, + "n": 5 + }, + { + "month": "2025-12", + "mean": 23.6, + "median": 24.0, + "p10": 19.6, + "p25": 22.0, + "p75": 26.0, + "p90": 27.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 27.2, + "median": 28.0, + "p10": 22.8, + "p25": 24.0, + "p75": 30.0, + "p90": 31.2, + "n": 5 + }, + { + "month": "2026-02", + "mean": 24.2, + "median": 23.0, + "p10": 20.2, + "p25": 22.0, + "p75": 27.0, + "p90": 28.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 27.6, + "median": 27.0, + "p10": 23.8, + "p25": 25.0, + "p75": 29.0, + "p90": 32.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 24.8, + "median": 25.0, + "p10": 21.2, + "p25": 23.0, + "p75": 27.0, + "p90": 28.2, + "n": 5 + }, + { + "month": "2026-05", + "mean": 24.0, + "median": 24.0, + "p10": 20.8, + "p25": 22.0, + "p75": 26.0, + "p90": 27.2, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 48.3, + "median": 46.0, + "std": 19.8, + "min": 5, + "max": 130, + "p25": 38.5, + "p75": 54.5, + "p85": 61.0, + "p95": 87.7 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 3.2, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 35 + }, + { + "date": "2022-04-15", + "value": 62 + }, + { + "date": "2022-04-28", + "value": 18 + }, + { + "date": "2022-08-05", + "value": 88 + }, + { + "date": "2022-08-12", + "value": 42 + }, + { + "date": "2022-08-20", + "value": 55 + }, + { + "date": "2022-08-28", + "value": 30 + }, + { + "date": "2023-01-10", + "value": 72 + }, + { + "date": "2023-01-22", + "value": 25 + }, + { + "date": "2023-01-30", + "value": 48 + }, + { + "date": "2023-06-05", + "value": 15 + }, + { + "date": "2023-06-18", + "value": 95 + }, + { + "date": "2023-10-03", + "value": 130 + }, + { + "date": "2023-10-10", + "value": 45 + }, + { + "date": "2023-10-18", + "value": 38 + }, + { + "date": "2023-10-25", + "value": 65 + }, + { + "date": "2023-10-30", + "value": 22 + }, + { + "date": "2024-03-05", + "value": 78 + }, + { + "date": "2024-03-12", + "value": 5 + }, + { + "date": "2024-03-20", + "value": 55 + }, + { + "date": "2024-03-28", + "value": 40 + }, + { + "date": "2024-07-08", + "value": 28 + }, + { + "date": "2024-07-15", + "value": 85 + }, + { + "date": "2024-07-22", + "value": 50 + }, + { + "date": "2024-11-04", + "value": 110 + }, + { + "date": "2024-11-11", + "value": 32 + }, + { + "date": "2024-11-18", + "value": 68 + }, + { + "date": "2024-11-25", + "value": 45 + }, + { + "date": "2024-11-30", + "value": 92 + }, + { + "date": "2025-03-03", + "value": 20 + }, + { + "date": "2025-03-10", + "value": 58 + }, + { + "date": "2025-03-17", + "value": 35 + }, + { + "date": "2025-03-24", + "value": 42 + }, + { + "date": "2025-07-02", + "value": 75 + }, + { + "date": "2025-07-09", + "value": 12 + }, + { + "date": "2025-07-16", + "value": 48 + }, + { + "date": "2025-07-23", + "value": 60 + }, + { + "date": "2025-07-30", + "value": 38 + }, + { + "date": "2025-09-05", + "value": 49 + }, + { + "date": "2025-09-11", + "value": 54 + }, + { + "date": "2025-09-17", + "value": 34 + }, + { + "date": "2025-09-23", + "value": 39 + }, + { + "date": "2025-09-29", + "value": 42 + }, + { + "date": "2025-10-06", + "value": 61 + }, + { + "date": "2025-10-12", + "value": 41 + }, + { + "date": "2025-10-18", + "value": 46 + }, + { + "date": "2025-10-24", + "value": 49 + }, + { + "date": "2025-10-30", + "value": 53 + }, + { + "date": "2025-11-04", + "value": 36 + }, + { + "date": "2025-11-10", + "value": 41 + }, + { + "date": "2025-11-16", + "value": 44 + }, + { + "date": "2025-11-22", + "value": 48 + }, + { + "date": "2025-11-28", + "value": 52 + }, + { + "date": "2025-12-05", + "value": 36 + }, + { + "date": "2025-12-11", + "value": 39 + }, + { + "date": "2025-12-17", + "value": 43 + }, + { + "date": "2025-12-23", + "value": 47 + }, + { + "date": "2025-12-29", + "value": 51 + }, + { + "date": "2026-01-06", + "value": 47 + }, + { + "date": "2026-01-12", + "value": 50 + }, + { + "date": "2026-01-18", + "value": 54 + }, + { + "date": "2026-01-24", + "value": 58 + }, + { + "date": "2026-01-30", + "value": 39 + }, + { + "date": "2026-02-04", + "value": 45 + }, + { + "date": "2026-02-10", + "value": 49 + }, + { + "date": "2026-02-16", + "value": 54 + }, + { + "date": "2026-02-22", + "value": 34 + }, + { + "date": "2026-02-28", + "value": 39 + }, + { + "date": "2026-03-05", + "value": 56 + }, + { + "date": "2026-03-11", + "value": 61 + }, + { + "date": "2026-03-17", + "value": 41 + }, + { + "date": "2026-03-23", + "value": 46 + }, + { + "date": "2026-03-29", + "value": 49 + }, + { + "date": "2026-04-06", + "value": 56 + }, + { + "date": "2026-04-12", + "value": 36 + }, + { + "date": "2026-04-18", + "value": 41 + }, + { + "date": "2026-04-24", + "value": 44 + }, + { + "date": "2026-04-30", + "value": 48 + }, + { + "date": "2026-05-04", + "value": 32 + }, + { + "date": "2026-05-10", + "value": 36 + }, + { + "date": "2026-05-16", + "value": 39 + }, + { + "date": "2026-05-22", + "value": 43 + }, + { + "date": "2026-05-28", + "value": 47 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 38.3, + "median": 35.0, + "p10": 21.4, + "p25": 26.5, + "p75": 48.5, + "p90": 56.6, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 53.8, + "median": 48.5, + "p10": 33.6, + "p25": 39.0, + "p75": 63.3, + "p90": 78.1, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 48.3, + "median": 48.0, + "p10": 29.6, + "p25": 36.5, + "p75": 60.0, + "p90": 67.2, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 55.0, + "median": 55.0, + "p10": 23.0, + "p25": 35.0, + "p75": 75.0, + "p90": 87.0, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 60.0, + "median": 45.0, + "p10": 28.4, + "p25": 38.0, + "p75": 65.0, + "p90": 104.0, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 44.5, + "median": 47.5, + "p10": 15.5, + "p25": 31.3, + "p75": 60.8, + "p90": 71.1, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 54.3, + "median": 50.0, + "p10": 32.4, + "p25": 39.0, + "p75": 67.5, + "p90": 78.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 69.4, + "median": 68.0, + "p10": 37.2, + "p25": 45.0, + "p75": 92.0, + "p90": 102.8, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 38.8, + "median": 38.5, + "p10": 24.5, + "p25": 31.3, + "p75": 46.0, + "p90": 53.2, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 46.6, + "median": 48.0, + "p10": 22.4, + "p25": 38.0, + "p75": 60.0, + "p90": 69.0, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 43.6, + "median": 42.0, + "p10": 36.0, + "p25": 39.0, + "p75": 49.0, + "p90": 52.0, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 50.0, + "median": 49.0, + "p10": 43.0, + "p25": 46.0, + "p75": 53.0, + "p90": 57.8, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 44.2, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 43.2, + "median": 43.0, + "p10": 37.2, + "p25": 39.0, + "p75": 47.0, + "p90": 49.4, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 49.6, + "median": 50.0, + "p10": 42.2, + "p25": 47.0, + "p75": 54.0, + "p90": 56.4, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 44.2, + "median": 45.0, + "p10": 36.0, + "p25": 39.0, + "p75": 49.0, + "p90": 52.0, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 50.6, + "median": 49.0, + "p10": 43.0, + "p25": 46.0, + "p75": 56.0, + "p90": 59.0, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 45.0, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 48.0, + "p90": 52.8, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 39.4, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 43.0, + "p90": 45.4, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 36.6, + "median": 34.0, + "std": 15.8, + "min": 3, + "max": 98, + "p25": 28.0, + "p75": 41.0, + "p85": 45.0, + "p95": 69.2 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 1.8, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 28 + }, + { + "date": "2022-05-10", + "value": 45 + }, + { + "date": "2022-05-18", + "value": 12 + }, + { + "date": "2022-05-25", + "value": 62 + }, + { + "date": "2023-02-06", + "value": 33 + }, + { + "date": "2023-02-14", + "value": 78 + }, + { + "date": "2023-02-22", + "value": 20 + }, + { + "date": "2023-02-28", + "value": 55 + }, + { + "date": "2023-09-05", + "value": 8 + }, + { + "date": "2023-09-15", + "value": 42 + }, + { + "date": "2023-09-25", + "value": 65 + }, + { + "date": "2024-04-03", + "value": 38 + }, + { + "date": "2024-04-10", + "value": 15 + }, + { + "date": "2024-04-17", + "value": 72 + }, + { + "date": "2024-04-24", + "value": 25 + }, + { + "date": "2024-10-02", + "value": 48 + }, + { + "date": "2024-10-09", + "value": 3 + }, + { + "date": "2024-10-16", + "value": 85 + }, + { + "date": "2024-10-23", + "value": 30 + }, + { + "date": "2024-10-30", + "value": 55 + }, + { + "date": "2025-04-07", + "value": 22 + }, + { + "date": "2025-04-14", + "value": 40 + }, + { + "date": "2025-04-21", + "value": 98 + }, + { + "date": "2025-04-28", + "value": 18 + }, + { + "date": "2025-09-04", + "value": 39 + }, + { + "date": "2025-09-10", + "value": 41 + }, + { + "date": "2025-09-16", + "value": 45 + }, + { + "date": "2025-09-22", + "value": 30 + }, + { + "date": "2025-09-28", + "value": 34 + }, + { + "date": "2025-10-05", + "value": 38 + }, + { + "date": "2025-10-11", + "value": 41 + }, + { + "date": "2025-10-17", + "value": 27 + }, + { + "date": "2025-10-23", + "value": 30 + }, + { + "date": "2025-10-29", + "value": 32 + }, + { + "date": "2025-11-06", + "value": 38 + }, + { + "date": "2025-11-12", + "value": 23 + }, + { + "date": "2025-11-18", + "value": 27 + }, + { + "date": "2025-11-24", + "value": 29 + }, + { + "date": "2025-11-30", + "value": 32 + }, + { + "date": "2025-12-04", + "value": 28 + }, + { + "date": "2025-12-10", + "value": 32 + }, + { + "date": "2025-12-16", + "value": 34 + }, + { + "date": "2025-12-22", + "value": 37 + }, + { + "date": "2025-12-28", + "value": 40 + }, + { + "date": "2026-01-05", + "value": 28 + }, + { + "date": "2026-01-11", + "value": 31 + }, + { + "date": "2026-01-17", + "value": 33 + }, + { + "date": "2026-01-23", + "value": 36 + }, + { + "date": "2026-01-29", + "value": 39 + }, + { + "date": "2026-02-06", + "value": 36 + }, + { + "date": "2026-02-12", + "value": 39 + }, + { + "date": "2026-02-18", + "value": 41 + }, + { + "date": "2026-02-24", + "value": 45 + }, + { + "date": "2026-02-30", + "value": 30 + }, + { + "date": "2026-03-04", + "value": 35 + }, + { + "date": "2026-03-10", + "value": 38 + }, + { + "date": "2026-03-16", + "value": 41 + }, + { + "date": "2026-03-22", + "value": 27 + }, + { + "date": "2026-03-28", + "value": 30 + }, + { + "date": "2026-04-05", + "value": 34 + }, + { + "date": "2026-04-11", + "value": 38 + }, + { + "date": "2026-04-17", + "value": 23 + }, + { + "date": "2026-04-23", + "value": 27 + }, + { + "date": "2026-04-29", + "value": 29 + }, + { + "date": "2026-05-06", + "value": 43 + }, + { + "date": "2026-05-12", + "value": 28 + }, + { + "date": "2026-05-18", + "value": 32 + }, + { + "date": "2026-05-24", + "value": 34 + }, + { + "date": "2026-05-30", + "value": 37 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 36.8, + "median": 36.5, + "p10": 16.8, + "p25": 24.0, + "p75": 49.3, + "p90": 56.9, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 46.5, + "median": 44.0, + "p10": 23.9, + "p25": 29.8, + "p75": 60.8, + "p90": 71.1, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 38.3, + "median": 42.0, + "p10": 14.8, + "p25": 25.0, + "p75": 53.5, + "p90": 60.4, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 37.5, + "median": 31.5, + "p10": 18.0, + "p25": 22.5, + "p75": 46.5, + "p90": 61.8, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 44.2, + "median": 48.0, + "p10": 13.8, + "p25": 30.0, + "p75": 55.0, + "p90": 73.0, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 44.5, + "median": 31.0, + "p10": 19.2, + "p25": 21.0, + "p75": 54.5, + "p90": 80.6, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 37.8, + "median": 39.0, + "p10": 31.6, + "p25": 34.0, + "p75": 41.0, + "p90": 43.4, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 33.6, + "median": 32.0, + "p10": 28.2, + "p25": 30.0, + "p75": 38.0, + "p90": 39.8, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 29.8, + "median": 29.0, + "p10": 24.6, + "p25": 27.0, + "p75": 32.0, + "p90": 35.6, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 34.2, + "median": 34.0, + "p10": 29.6, + "p25": 32.0, + "p75": 37.0, + "p90": 38.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 33.4, + "median": 33.0, + "p10": 29.2, + "p25": 31.0, + "p75": 36.0, + "p90": 37.8, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 38.2, + "median": 39.0, + "p10": 32.4, + "p25": 36.0, + "p75": 41.0, + "p90": 43.4, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 34.2, + "median": 35.0, + "p10": 28.2, + "p25": 30.0, + "p75": 38.0, + "p90": 39.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 30.2, + "median": 29.0, + "p10": 24.6, + "p25": 27.0, + "p75": 34.0, + "p90": 36.4, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 34.8, + "median": 34.0, + "p10": 29.6, + "p25": 32.0, + "p75": 37.0, + "p90": 40.6, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 43.9, + "median": 41.0, + "std": 19.1, + "min": 4, + "max": 115, + "p25": 34.3, + "p75": 50.0, + "p85": 54.0, + "p95": 81.9 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 5.5, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 40 + }, + { + "date": "2022-06-15", + "value": 22 + }, + { + "date": "2022-06-25", + "value": 68 + }, + { + "date": "2023-03-08", + "value": 4 + }, + { + "date": "2023-03-15", + "value": 55 + }, + { + "date": "2023-03-22", + "value": 115 + }, + { + "date": "2023-03-29", + "value": 30 + }, + { + "date": "2023-11-06", + "value": 62 + }, + { + "date": "2023-11-13", + "value": 18 + }, + { + "date": "2023-11-20", + "value": 85 + }, + { + "date": "2024-06-03", + "value": 35 + }, + { + "date": "2024-06-10", + "value": 72 + }, + { + "date": "2024-06-17", + "value": 10 + }, + { + "date": "2024-06-24", + "value": 48 + }, + { + "date": "2024-06-30", + "value": 95 + }, + { + "date": "2025-01-07", + "value": 28 + }, + { + "date": "2025-01-14", + "value": 52 + }, + { + "date": "2025-01-21", + "value": 15 + }, + { + "date": "2025-01-28", + "value": 78 + }, + { + "date": "2025-08-04", + "value": 42 + }, + { + "date": "2025-08-08", + "value": 8 + }, + { + "date": "2025-08-12", + "value": 65 + }, + { + "date": "2025-08-16", + "value": 33 + }, + { + "date": "2025-08-20", + "value": 100 + }, + { + "date": "2025-08-24", + "value": 20 + }, + { + "date": "2025-09-06", + "value": 41 + }, + { + "date": "2025-09-12", + "value": 45 + }, + { + "date": "2025-09-18", + "value": 48 + }, + { + "date": "2025-09-24", + "value": 52 + }, + { + "date": "2025-09-30", + "value": 34 + }, + { + "date": "2025-10-04", + "value": 40 + }, + { + "date": "2025-10-10", + "value": 44 + }, + { + "date": "2025-10-16", + "value": 48 + }, + { + "date": "2025-10-22", + "value": 30 + }, + { + "date": "2025-10-28", + "value": 34 + }, + { + "date": "2025-11-05", + "value": 50 + }, + { + "date": "2025-11-11", + "value": 54 + }, + { + "date": "2025-11-17", + "value": 36 + }, + { + "date": "2025-11-23", + "value": 41 + }, + { + "date": "2025-11-29", + "value": 44 + }, + { + "date": "2025-12-06", + "value": 50 + }, + { + "date": "2025-12-12", + "value": 32 + }, + { + "date": "2025-12-18", + "value": 36 + }, + { + "date": "2025-12-24", + "value": 39 + }, + { + "date": "2025-12-30", + "value": 43 + }, + { + "date": "2026-01-04", + "value": 28 + }, + { + "date": "2026-01-10", + "value": 32 + }, + { + "date": "2026-01-16", + "value": 35 + }, + { + "date": "2026-01-22", + "value": 38 + }, + { + "date": "2026-01-28", + "value": 42 + }, + { + "date": "2026-02-05", + "value": 39 + }, + { + "date": "2026-02-11", + "value": 41 + }, + { + "date": "2026-02-17", + "value": 45 + }, + { + "date": "2026-02-23", + "value": 48 + }, + { + "date": "2026-02-29", + "value": 52 + }, + { + "date": "2026-03-06", + "value": 37 + }, + { + "date": "2026-03-12", + "value": 40 + }, + { + "date": "2026-03-18", + "value": 44 + }, + { + "date": "2026-03-24", + "value": 48 + }, + { + "date": "2026-03-30", + "value": 30 + }, + { + "date": "2026-04-04", + "value": 47 + }, + { + "date": "2026-04-10", + "value": 50 + }, + { + "date": "2026-04-16", + "value": 54 + }, + { + "date": "2026-04-22", + "value": 36 + }, + { + "date": "2026-04-28", + "value": 41 + }, + { + "date": "2026-05-05", + "value": 46 + }, + { + "date": "2026-05-11", + "value": 50 + }, + { + "date": "2026-05-17", + "value": 32 + }, + { + "date": "2026-05-23", + "value": 36 + }, + { + "date": "2026-05-29", + "value": 39 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 43.3, + "median": 40.0, + "p10": 25.6, + "p25": 31.0, + "p75": 54.0, + "p90": 62.4, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 51.0, + "median": 42.5, + "p10": 11.8, + "p25": 23.5, + "p75": 70.0, + "p90": 97.0, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 55.0, + "median": 62.0, + "p10": 26.8, + "p25": 40.0, + "p75": 73.5, + "p90": 80.4, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 52.0, + "median": 48.0, + "p10": 20.0, + "p25": 35.0, + "p75": 72.0, + "p90": 85.8, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 43.3, + "median": 40.0, + "p10": 18.9, + "p25": 24.8, + "p75": 58.5, + "p90": 70.2, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 44.7, + "median": 37.5, + "p10": 14.0, + "p25": 23.3, + "p75": 59.3, + "p90": 82.5, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 44.0, + "median": 45.0, + "p10": 36.8, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 39.2, + "median": 40.0, + "p10": 31.6, + "p25": 34.0, + "p75": 44.0, + "p90": 46.4, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 45.0, + "median": 44.0, + "p10": 38.0, + "p25": 41.0, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 40.0, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 43.0, + "p90": 47.2, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 35.0, + "median": 35.0, + "p10": 29.6, + "p25": 32.0, + "p75": 38.0, + "p90": 40.4, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 45.0, + "median": 45.0, + "p10": 39.8, + "p25": 41.0, + "p75": 48.0, + "p90": 50.4, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 39.8, + "median": 40.0, + "p10": 32.8, + "p25": 37.0, + "p75": 44.0, + "p90": 46.4, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 45.6, + "median": 47.0, + "p10": 38.0, + "p25": 41.0, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 40.6, + "median": 39.0, + "p10": 33.6, + "p25": 36.0, + "p75": 46.0, + "p90": 48.4, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 4.4, + "median": 4.0, + "std": 1.8, + "min": 1, + "max": 14, + "p25": 3.3, + "p75": 5.0, + "p85": 5.0, + "p95": 6.6 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 3 + }, + { + "date": "2022-07-05", + "value": 5 + }, + { + "date": "2022-10-12", + "value": 2 + }, + { + "date": "2023-01-20", + "value": 7 + }, + { + "date": "2023-04-15", + "value": 4 + }, + { + "date": "2023-07-28", + "value": 6 + }, + { + "date": "2023-10-05", + "value": 3 + }, + { + "date": "2024-01-12", + "value": 14 + }, + { + "date": "2024-04-22", + "value": 4 + }, + { + "date": "2024-07-10", + "value": 8 + }, + { + "date": "2024-10-18", + "value": 3 + }, + { + "date": "2025-01-25", + "value": 5 + }, + { + "date": "2025-05-08", + "value": 1 + }, + { + "date": "2025-08-15", + "value": 6 + }, + { + "date": "2025-09-04", + "value": 3 + }, + { + "date": "2025-09-10", + "value": 4 + }, + { + "date": "2025-09-16", + "value": 4 + }, + { + "date": "2025-09-22", + "value": 4 + }, + { + "date": "2025-10-05", + "value": 3 + }, + { + "date": "2025-10-11", + "value": 4 + }, + { + "date": "2025-10-17", + "value": 4 + }, + { + "date": "2025-10-23", + "value": 4 + }, + { + "date": "2025-11-06", + "value": 4 + }, + { + "date": "2025-11-12", + "value": 5 + }, + { + "date": "2025-11-18", + "value": 5 + }, + { + "date": "2025-11-24", + "value": 5 + }, + { + "date": "2025-12-04", + "value": 4 + }, + { + "date": "2025-12-10", + "value": 5 + }, + { + "date": "2025-12-16", + "value": 5 + }, + { + "date": "2025-12-22", + "value": 3 + }, + { + "date": "2026-01-05", + "value": 4 + }, + { + "date": "2026-01-11", + "value": 5 + }, + { + "date": "2026-01-17", + "value": 3 + }, + { + "date": "2026-01-23", + "value": 3 + }, + { + "date": "2026-02-06", + "value": 5 + }, + { + "date": "2026-02-12", + "value": 3 + }, + { + "date": "2026-02-18", + "value": 4 + }, + { + "date": "2026-02-24", + "value": 4 + }, + { + "date": "2026-03-04", + "value": 3 + }, + { + "date": "2026-03-10", + "value": 3 + }, + { + "date": "2026-03-16", + "value": 4 + }, + { + "date": "2026-03-22", + "value": 4 + }, + { + "date": "2026-04-05", + "value": 4 + }, + { + "date": "2026-04-11", + "value": 4 + }, + { + "date": "2026-04-17", + "value": 5 + }, + { + "date": "2026-04-23", + "value": 5 + }, + { + "date": "2026-05-06", + "value": 4 + }, + { + "date": "2026-05-12", + "value": 4 + }, + { + "date": "2026-05-18", + "value": 5 + }, + { + "date": "2026-05-24", + "value": 5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 14.0, + "median": 14.0, + "p10": 14.0, + "p25": 14.0, + "p75": 14.0, + "p90": 14.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 4.8, + "median": 5.0, + "p10": 4.3, + "p25": 4.8, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 4.3, + "median": 4.5, + "p10": 3.3, + "p25": 3.8, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.8, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.3, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.0, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.3, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 4.5, + "median": 4.5, + "p10": 4.0, + "p25": 4.0, + "p75": 5.0, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.5, + "median": 4.5, + "p10": 4.0, + "p25": 4.0, + "p75": 5.0, + "p90": 5.0, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 17.4, + "median": 16.0, + "std": 9.0, + "min": 2, + "max": 55, + "p25": 13.0, + "p75": 19.0, + "p85": 20.4, + "p95": 37.0 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 12.5, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 12 + }, + { + "date": "2022-05-15", + "value": 25 + }, + { + "date": "2022-05-22", + "value": 8 + }, + { + "date": "2022-11-03", + "value": 35 + }, + { + "date": "2022-11-10", + "value": 15 + }, + { + "date": "2022-11-18", + "value": 5 + }, + { + "date": "2022-11-25", + "value": 22 + }, + { + "date": "2023-05-08", + "value": 18 + }, + { + "date": "2023-05-15", + "value": 40 + }, + { + "date": "2023-05-22", + "value": 10 + }, + { + "date": "2023-11-06", + "value": 55 + }, + { + "date": "2023-11-13", + "value": 2 + }, + { + "date": "2023-11-20", + "value": 28 + }, + { + "date": "2023-11-27", + "value": 15 + }, + { + "date": "2023-11-30", + "value": 8 + }, + { + "date": "2024-05-06", + "value": 20 + }, + { + "date": "2024-05-13", + "value": 45 + }, + { + "date": "2024-05-20", + "value": 12 + }, + { + "date": "2024-05-27", + "value": 3 + }, + { + "date": "2024-11-04", + "value": 18 + }, + { + "date": "2024-11-11", + "value": 30 + }, + { + "date": "2024-11-18", + "value": 8 + }, + { + "date": "2025-05-05", + "value": 22 + }, + { + "date": "2025-05-09", + "value": 35 + }, + { + "date": "2025-05-13", + "value": 5 + }, + { + "date": "2025-05-17", + "value": 15 + }, + { + "date": "2025-05-21", + "value": 42 + }, + { + "date": "2025-05-25", + "value": 10 + }, + { + "date": "2025-09-05", + "value": 14 + }, + { + "date": "2025-09-11", + "value": 16 + }, + { + "date": "2025-09-17", + "value": 17 + }, + { + "date": "2025-09-23", + "value": 18 + }, + { + "date": "2025-09-29", + "value": 19 + }, + { + "date": "2025-10-06", + "value": 14 + }, + { + "date": "2025-10-12", + "value": 15 + }, + { + "date": "2025-10-18", + "value": 16 + }, + { + "date": "2025-10-24", + "value": 18 + }, + { + "date": "2025-10-30", + "value": 11 + }, + { + "date": "2025-11-04", + "value": 18 + }, + { + "date": "2025-11-10", + "value": 19 + }, + { + "date": "2025-11-16", + "value": 20 + }, + { + "date": "2025-11-22", + "value": 14 + }, + { + "date": "2025-11-28", + "value": 15 + }, + { + "date": "2025-12-05", + "value": 17 + }, + { + "date": "2025-12-11", + "value": 19 + }, + { + "date": "2025-12-17", + "value": 12 + }, + { + "date": "2025-12-23", + "value": 14 + }, + { + "date": "2025-12-29", + "value": 15 + }, + { + "date": "2026-01-06", + "value": 17 + }, + { + "date": "2026-01-12", + "value": 11 + }, + { + "date": "2026-01-18", + "value": 12 + }, + { + "date": "2026-01-24", + "value": 13 + }, + { + "date": "2026-01-30", + "value": 14 + }, + { + "date": "2026-02-04", + "value": 13 + }, + { + "date": "2026-02-10", + "value": 14 + }, + { + "date": "2026-02-16", + "value": 16 + }, + { + "date": "2026-02-22", + "value": 17 + }, + { + "date": "2026-02-28", + "value": 18 + }, + { + "date": "2026-03-05", + "value": 13 + }, + { + "date": "2026-03-11", + "value": 14 + }, + { + "date": "2026-03-17", + "value": 15 + }, + { + "date": "2026-03-23", + "value": 16 + }, + { + "date": "2026-03-29", + "value": 18 + }, + { + "date": "2026-04-06", + "value": 16 + }, + { + "date": "2026-04-12", + "value": 18 + }, + { + "date": "2026-04-18", + "value": 19 + }, + { + "date": "2026-04-24", + "value": 20 + }, + { + "date": "2026-04-30", + "value": 14 + }, + { + "date": "2026-05-04", + "value": 16 + }, + { + "date": "2026-05-10", + "value": 17 + }, + { + "date": "2026-05-16", + "value": 19 + }, + { + "date": "2026-05-22", + "value": 12 + }, + { + "date": "2026-05-28", + "value": 14 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 15.0, + "median": 12.0, + "p10": 8.8, + "p25": 10.0, + "p75": 18.5, + "p90": 22.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 19.3, + "median": 18.5, + "p10": 8.0, + "p25": 12.5, + "p75": 25.3, + "p90": 31.1, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 22.7, + "median": 18.0, + "p10": 11.6, + "p25": 14.0, + "p75": 29.0, + "p90": 35.6, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 21.6, + "median": 15.0, + "p10": 4.4, + "p25": 8.0, + "p75": 28.0, + "p90": 44.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 20.0, + "median": 16.0, + "p10": 5.7, + "p25": 9.8, + "p75": 26.3, + "p90": 37.5, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 18.7, + "median": 18.0, + "p10": 10.0, + "p25": 13.0, + "p75": 24.0, + "p90": 27.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 21.5, + "median": 18.5, + "p10": 7.5, + "p25": 11.3, + "p75": 31.8, + "p90": 38.5, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 16.8, + "median": 17.0, + "p10": 14.8, + "p25": 16.0, + "p75": 18.0, + "p90": 18.6, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 14.8, + "median": 15.0, + "p10": 12.2, + "p25": 14.0, + "p75": 16.0, + "p90": 17.2, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 17.2, + "median": 18.0, + "p10": 14.4, + "p25": 15.0, + "p75": 19.0, + "p90": 19.6, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 15.4, + "median": 15.0, + "p10": 12.8, + "p25": 14.0, + "p75": 17.0, + "p90": 18.2, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 13.4, + "median": 13.0, + "p10": 11.4, + "p25": 12.0, + "p75": 14.0, + "p90": 15.8, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 15.6, + "median": 16.0, + "p10": 13.4, + "p25": 14.0, + "p75": 17.0, + "p90": 17.6, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 15.2, + "median": 15.0, + "p10": 13.4, + "p25": 14.0, + "p75": 16.0, + "p90": 17.2, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 17.4, + "median": 18.0, + "p10": 14.8, + "p25": 16.0, + "p75": 19.0, + "p90": 19.6, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 15.6, + "median": 16.0, + "p10": 12.8, + "p25": 14.0, + "p75": 17.0, + "p90": 18.2, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 3.2, + "median": 3.0, + "std": 1.4, + "min": 0, + "max": 10, + "p25": 3.0, + "p75": 4.0, + "p85": 4.0, + "p95": 5.2 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 2 + }, + { + "date": "2022-06-10", + "value": 3 + }, + { + "date": "2022-07-15", + "value": 1 + }, + { + "date": "2022-08-22", + "value": 4 + }, + { + "date": "2022-10-05", + "value": 2 + }, + { + "date": "2022-11-18", + "value": 5 + }, + { + "date": "2023-01-10", + "value": 3 + }, + { + "date": "2023-03-25", + "value": 7 + }, + { + "date": "2023-05-12", + "value": 2 + }, + { + "date": "2023-07-08", + "value": 4 + }, + { + "date": "2023-09-15", + "value": 1 + }, + { + "date": "2023-11-22", + "value": 3 + }, + { + "date": "2024-01-18", + "value": 10 + }, + { + "date": "2024-03-08", + "value": 3 + }, + { + "date": "2024-05-15", + "value": 2 + }, + { + "date": "2024-07-22", + "value": 5 + }, + { + "date": "2024-09-10", + "value": 0 + }, + { + "date": "2024-11-05", + "value": 4 + }, + { + "date": "2025-01-15", + "value": 3 + }, + { + "date": "2025-03-20", + "value": 2 + }, + { + "date": "2025-05-28", + "value": 6 + }, + { + "date": "2025-08-05", + "value": 3 + }, + { + "date": "2025-09-05", + "value": 4 + }, + { + "date": "2025-09-11", + "value": 4 + }, + { + "date": "2025-09-17", + "value": 3 + }, + { + "date": "2025-09-23", + "value": 3 + }, + { + "date": "2025-10-06", + "value": 4 + }, + { + "date": "2025-10-12", + "value": 2 + }, + { + "date": "2025-10-18", + "value": 3 + }, + { + "date": "2025-10-24", + "value": 3 + }, + { + "date": "2025-11-04", + "value": 2 + }, + { + "date": "2025-11-10", + "value": 2 + }, + { + "date": "2025-11-16", + "value": 3 + }, + { + "date": "2025-11-22", + "value": 3 + }, + { + "date": "2025-12-05", + "value": 3 + }, + { + "date": "2025-12-11", + "value": 3 + }, + { + "date": "2025-12-17", + "value": 3 + }, + { + "date": "2025-12-23", + "value": 4 + }, + { + "date": "2026-01-06", + "value": 3 + }, + { + "date": "2026-01-12", + "value": 3 + }, + { + "date": "2026-01-18", + "value": 3 + }, + { + "date": "2026-01-24", + "value": 4 + }, + { + "date": "2026-02-04", + "value": 4 + }, + { + "date": "2026-02-10", + "value": 4 + }, + { + "date": "2026-02-16", + "value": 4 + }, + { + "date": "2026-02-22", + "value": 3 + }, + { + "date": "2026-03-05", + "value": 3 + }, + { + "date": "2026-03-11", + "value": 4 + }, + { + "date": "2026-03-17", + "value": 2 + }, + { + "date": "2026-03-23", + "value": 3 + }, + { + "date": "2026-04-06", + "value": 3 + }, + { + "date": "2026-04-12", + "value": 2 + }, + { + "date": "2026-04-18", + "value": 2 + }, + { + "date": "2026-04-24", + "value": 3 + }, + { + "date": "2026-05-04", + "value": 3 + }, + { + "date": "2026-05-10", + "value": 3 + }, + { + "date": "2026-05-16", + "value": 3 + }, + { + "date": "2026-05-22", + "value": 3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2022-08", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2025-05", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.0, + "p25": 2.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.8, + "median": 4.0, + "p10": 3.3, + "p25": 3.8, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.0, + "p25": 2.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 3.4, + "median": 3.0, + "std": 1.8, + "min": 0, + "max": 13, + "p25": 3.0, + "p75": 4.0, + "p85": 4.0, + "p95": 6.2 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 2 + }, + { + "date": "2022-06-13", + "value": 1 + }, + { + "date": "2022-07-16", + "value": 3 + }, + { + "date": "2022-08-26", + "value": 2 + }, + { + "date": "2022-10-07", + "value": 5 + }, + { + "date": "2022-11-23", + "value": 2 + }, + { + "date": "2023-01-13", + "value": 4 + }, + { + "date": "2023-04-01", + "value": 3 + }, + { + "date": "2023-05-14", + "value": 6 + }, + { + "date": "2023-07-12", + "value": 2 + }, + { + "date": "2023-09-16", + "value": 13 + }, + { + "date": "2023-11-25", + "value": 3 + }, + { + "date": "2024-01-28", + "value": 7 + }, + { + "date": "2024-03-11", + "value": 1 + }, + { + "date": "2024-05-17", + "value": 4 + }, + { + "date": "2024-07-27", + "value": 5 + }, + { + "date": "2024-09-10", + "value": 2 + }, + { + "date": "2024-11-09", + "value": 0 + }, + { + "date": "2025-01-18", + "value": 3 + }, + { + "date": "2025-03-22", + "value": 8 + }, + { + "date": "2025-06-03", + "value": 2 + }, + { + "date": "2025-08-08", + "value": 5 + }, + { + "date": "2025-09-04", + "value": 2 + }, + { + "date": "2025-09-10", + "value": 3 + }, + { + "date": "2025-09-16", + "value": 3 + }, + { + "date": "2025-09-22", + "value": 3 + }, + { + "date": "2025-10-05", + "value": 3 + }, + { + "date": "2025-10-11", + "value": 3 + }, + { + "date": "2025-10-17", + "value": 4 + }, + { + "date": "2025-10-23", + "value": 4 + }, + { + "date": "2025-11-06", + "value": 3 + }, + { + "date": "2025-11-12", + "value": 3 + }, + { + "date": "2025-11-18", + "value": 3 + }, + { + "date": "2025-11-24", + "value": 4 + }, + { + "date": "2025-12-04", + "value": 3 + }, + { + "date": "2025-12-10", + "value": 3 + }, + { + "date": "2025-12-16", + "value": 3 + }, + { + "date": "2025-12-22", + "value": 2 + }, + { + "date": "2026-01-05", + "value": 4 + }, + { + "date": "2026-01-11", + "value": 4 + }, + { + "date": "2026-01-17", + "value": 3 + }, + { + "date": "2026-01-23", + "value": 3 + }, + { + "date": "2026-02-06", + "value": 4 + }, + { + "date": "2026-02-12", + "value": 2 + }, + { + "date": "2026-02-18", + "value": 3 + }, + { + "date": "2026-02-24", + "value": 3 + }, + { + "date": "2026-03-04", + "value": 3 + }, + { + "date": "2026-03-10", + "value": 3 + }, + { + "date": "2026-03-16", + "value": 3 + }, + { + "date": "2026-03-22", + "value": 4 + }, + { + "date": "2026-04-05", + "value": 3 + }, + { + "date": "2026-04-11", + "value": 3 + }, + { + "date": "2026-04-17", + "value": 3 + }, + { + "date": "2026-04-23", + "value": 3 + }, + { + "date": "2026-05-06", + "value": 3 + }, + { + "date": "2026-05-12", + "value": 3 + }, + { + "date": "2026-05-18", + "value": 3 + }, + { + "date": "2026-05-24", + "value": 3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2022-07", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2022-10", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2023-05", + "mean": 6.0, + "median": 6.0, + "p10": 6.0, + "p25": 6.0, + "p75": 6.0, + "p90": 6.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2023-09", + "mean": 13.0, + "median": 13.0, + "p10": 13.0, + "p25": 13.0, + "p75": 13.0, + "p90": 13.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2024-01", + "mean": 7.0, + "median": 7.0, + "p10": 7.0, + "p25": 7.0, + "p75": 7.0, + "p90": 7.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.0, + "median": 1.0, + "p10": 1.0, + "p25": 1.0, + "p75": 1.0, + "p90": 1.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 4.0, + "median": 4.0, + "p10": 4.0, + "p25": 4.0, + "p75": 4.0, + "p90": 4.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 8.0, + "median": 8.0, + "p10": 8.0, + "p25": 8.0, + "p75": 8.0, + "p90": 8.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.0, + "median": 2.0, + "p10": 2.0, + "p25": 2.0, + "p75": 2.0, + "p90": 2.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 5.0, + "median": 5.0, + "p10": 5.0, + "p25": 5.0, + "p75": 5.0, + "p90": 5.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.8, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.8, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.0, + "p25": 3.0, + "p75": 4.0, + "p90": 4.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.0, + "median": 3.0, + "p10": 2.3, + "p25": 2.8, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.3, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.3, + "p90": 3.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.0, + "median": 3.0, + "p10": 3.0, + "p25": 3.0, + "p75": 3.0, + "p90": 3.0, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 12.7, + "median": 12.0, + "std": 5.6, + "min": 2, + "max": 42, + "p25": 10.0, + "p75": 14.0, + "p85": 15.0, + "p95": 20.4 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 28.5, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 8 + }, + { + "date": "2023-03-25", + "value": 22 + }, + { + "date": "2023-09-20", + "value": 42 + }, + { + "date": "2024-03-15", + "value": 6 + }, + { + "date": "2024-03-28", + "value": 18 + }, + { + "date": "2024-09-05", + "value": 28 + }, + { + "date": "2024-09-15", + "value": 12 + }, + { + "date": "2024-09-25", + "value": 2 + }, + { + "date": "2025-03-10", + "value": 15 + }, + { + "date": "2025-03-22", + "value": 5 + }, + { + "date": "2025-07-08", + "value": 20 + }, + { + "date": "2025-07-22", + "value": 4 + }, + { + "date": "2025-09-05", + "value": 14 + }, + { + "date": "2025-09-11", + "value": 15 + }, + { + "date": "2025-09-17", + "value": 10 + }, + { + "date": "2025-09-23", + "value": 11 + }, + { + "date": "2025-09-29", + "value": 12 + }, + { + "date": "2025-10-06", + "value": 14 + }, + { + "date": "2025-10-12", + "value": 8 + }, + { + "date": "2025-10-18", + "value": 10 + }, + { + "date": "2025-10-24", + "value": 11 + }, + { + "date": "2025-10-30", + "value": 11 + }, + { + "date": "2025-11-04", + "value": 10 + }, + { + "date": "2025-11-10", + "value": 12 + }, + { + "date": "2025-11-16", + "value": 12 + }, + { + "date": "2025-11-22", + "value": 13 + }, + { + "date": "2025-11-28", + "value": 14 + }, + { + "date": "2025-12-05", + "value": 10 + }, + { + "date": "2025-12-11", + "value": 11 + }, + { + "date": "2025-12-17", + "value": 12 + }, + { + "date": "2025-12-23", + "value": 13 + }, + { + "date": "2025-12-29", + "value": 14 + }, + { + "date": "2026-01-06", + "value": 13 + }, + { + "date": "2026-01-12", + "value": 14 + }, + { + "date": "2026-01-18", + "value": 15 + }, + { + "date": "2026-01-24", + "value": 16 + }, + { + "date": "2026-01-30", + "value": 11 + }, + { + "date": "2026-02-04", + "value": 13 + }, + { + "date": "2026-02-10", + "value": 14 + }, + { + "date": "2026-02-16", + "value": 15 + }, + { + "date": "2026-02-22", + "value": 10 + }, + { + "date": "2026-02-28", + "value": 11 + }, + { + "date": "2026-03-05", + "value": 13 + }, + { + "date": "2026-03-11", + "value": 14 + }, + { + "date": "2026-03-17", + "value": 8 + }, + { + "date": "2026-03-23", + "value": 10 + }, + { + "date": "2026-03-29", + "value": 11 + }, + { + "date": "2026-04-06", + "value": 16 + }, + { + "date": "2026-04-12", + "value": 10 + }, + { + "date": "2026-04-18", + "value": 12 + }, + { + "date": "2026-04-24", + "value": 12 + }, + { + "date": "2026-04-30", + "value": 13 + }, + { + "date": "2026-05-04", + "value": 9 + }, + { + "date": "2026-05-10", + "value": 10 + }, + { + "date": "2026-05-16", + "value": 11 + }, + { + "date": "2026-05-22", + "value": 12 + }, + { + "date": "2026-05-28", + "value": 13 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 15.0, + "median": 15.0, + "p10": 9.4, + "p25": 11.5, + "p75": 18.5, + "p90": 20.6, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 12.0, + "median": 12.0, + "p10": 7.2, + "p25": 9.0, + "p75": 15.0, + "p90": 16.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 14.0, + "median": 12.0, + "p10": 4.0, + "p25": 7.0, + "p75": 20.0, + "p90": 24.8, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 10.0, + "median": 10.0, + "p10": 6.0, + "p25": 7.5, + "p75": 12.5, + "p90": 14.0, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 12.0, + "median": 12.0, + "p10": 5.6, + "p25": 8.0, + "p75": 16.0, + "p90": 18.4, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 12.4, + "median": 12.0, + "p10": 10.4, + "p25": 11.0, + "p75": 14.0, + "p90": 14.6, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 10.8, + "median": 11.0, + "p10": 8.8, + "p25": 10.0, + "p75": 11.0, + "p90": 12.8, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 12.2, + "median": 12.0, + "p10": 10.8, + "p25": 12.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 12.0, + "median": 12.0, + "p10": 10.4, + "p25": 11.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 13.8, + "median": 14.0, + "p10": 11.8, + "p25": 13.0, + "p75": 15.0, + "p90": 15.6, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 12.6, + "median": 13.0, + "p10": 10.4, + "p25": 11.0, + "p75": 14.0, + "p90": 14.6, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 11.2, + "median": 11.0, + "p10": 8.8, + "p25": 10.0, + "p75": 13.0, + "p90": 13.6, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 12.6, + "median": 12.0, + "p10": 10.8, + "p25": 12.0, + "p75": 13.0, + "p90": 14.8, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 11.0, + "median": 11.0, + "p10": 9.4, + "p25": 10.0, + "p75": 12.0, + "p90": 12.6, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 20.9, + "median": 21.0, + "std": 4.6, + "min": 12, + "max": 38, + "p25": 18.5, + "p75": 23.0, + "p85": 24.9, + "p95": 26.6 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 18 + }, + { + "date": "2023-10-12", + "value": 25 + }, + { + "date": "2024-04-08", + "value": 12 + }, + { + "date": "2024-09-20", + "value": 38 + }, + { + "date": "2024-10-15", + "value": 20 + }, + { + "date": "2025-03-25", + "value": 15 + }, + { + "date": "2025-04-10", + "value": 28 + }, + { + "date": "2025-07-30", + "value": 24 + }, + { + "date": "2025-09-04", + "value": 17 + }, + { + "date": "2025-09-10", + "value": 19 + }, + { + "date": "2025-09-16", + "value": 21 + }, + { + "date": "2025-10-05", + "value": 17 + }, + { + "date": "2025-10-11", + "value": 19 + }, + { + "date": "2025-10-17", + "value": 20 + }, + { + "date": "2025-11-06", + "value": 22 + }, + { + "date": "2025-11-12", + "value": 23 + }, + { + "date": "2025-11-18", + "value": 25 + }, + { + "date": "2025-12-04", + "value": 21 + }, + { + "date": "2025-12-10", + "value": 23 + }, + { + "date": "2025-12-16", + "value": 25 + }, + { + "date": "2026-01-05", + "value": 21 + }, + { + "date": "2026-01-11", + "value": 23 + }, + { + "date": "2026-01-17", + "value": 14 + }, + { + "date": "2026-02-06", + "value": 26 + }, + { + "date": "2026-02-12", + "value": 17 + }, + { + "date": "2026-02-18", + "value": 19 + }, + { + "date": "2026-03-04", + "value": 15 + }, + { + "date": "2026-03-10", + "value": 17 + }, + { + "date": "2026-03-16", + "value": 19 + }, + { + "date": "2026-04-05", + "value": 20 + }, + { + "date": "2026-04-11", + "value": 22 + }, + { + "date": "2026-04-17", + "value": 23 + }, + { + "date": "2026-05-06", + "value": 20 + }, + { + "date": "2026-05-12", + "value": 21 + }, + { + "date": "2026-05-18", + "value": 23 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-04", + "mean": 12.0, + "median": 12.0, + "p10": 12.0, + "p25": 12.0, + "p75": 12.0, + "p90": 12.0, + "n": 1 + }, + { + "month": "2024-09", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-10", + "mean": 20.0, + "median": 20.0, + "p10": 20.0, + "p25": 20.0, + "p75": 20.0, + "p90": 20.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 24.0, + "median": 24.0, + "p10": 24.0, + "p25": 24.0, + "p75": 24.0, + "p90": 24.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 19.0, + "median": 19.0, + "p10": 17.4, + "p25": 18.0, + "p75": 20.0, + "p90": 20.6, + "n": 3 + }, + { + "month": "2025-10", + "mean": 18.7, + "median": 19.0, + "p10": 17.4, + "p25": 18.0, + "p75": 19.5, + "p90": 19.8, + "n": 3 + }, + { + "month": "2025-11", + "mean": 23.3, + "median": 23.0, + "p10": 22.2, + "p25": 22.5, + "p75": 24.0, + "p90": 24.6, + "n": 3 + }, + { + "month": "2025-12", + "mean": 23.0, + "median": 23.0, + "p10": 21.4, + "p25": 22.0, + "p75": 24.0, + "p90": 24.6, + "n": 3 + }, + { + "month": "2026-01", + "mean": 19.3, + "median": 21.0, + "p10": 15.4, + "p25": 17.5, + "p75": 22.0, + "p90": 22.6, + "n": 3 + }, + { + "month": "2026-02", + "mean": 20.7, + "median": 19.0, + "p10": 17.4, + "p25": 18.0, + "p75": 22.5, + "p90": 24.6, + "n": 3 + }, + { + "month": "2026-03", + "mean": 17.0, + "median": 17.0, + "p10": 15.4, + "p25": 16.0, + "p75": 18.0, + "p90": 18.6, + "n": 3 + }, + { + "month": "2026-04", + "mean": 21.7, + "median": 22.0, + "p10": 20.4, + "p25": 21.0, + "p75": 22.5, + "p90": 22.8, + "n": 3 + }, + { + "month": "2026-05", + "mean": 21.3, + "median": 21.0, + "p10": 20.2, + "p25": 20.5, + "p75": 22.0, + "p90": 22.6, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 31.3, + "median": 30.5, + "std": 7.1, + "min": 15, + "max": 55, + "p25": 27.0, + "p75": 36.0, + "p85": 38.0, + "p95": 41.9 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 28 + }, + { + "date": "2022-11-30", + "value": 35 + }, + { + "date": "2023-03-15", + "value": 22 + }, + { + "date": "2023-07-10", + "value": 42 + }, + { + "date": "2023-10-25", + "value": 30 + }, + { + "date": "2024-02-08", + "value": 55 + }, + { + "date": "2024-05-20", + "value": 25 + }, + { + "date": "2024-08-12", + "value": 38 + }, + { + "date": "2024-11-05", + "value": 15 + }, + { + "date": "2025-01-22", + "value": 32 + }, + { + "date": "2025-04-10", + "value": 28 + }, + { + "date": "2025-06-18", + "value": 45 + }, + { + "date": "2025-07-15", + "value": 30 + }, + { + "date": "2025-08-05", + "value": 22 + }, + { + "date": "2025-09-05", + "value": 36 + }, + { + "date": "2025-09-10", + "value": 38 + }, + { + "date": "2025-09-11", + "value": 39 + }, + { + "date": "2025-09-17", + "value": 26 + }, + { + "date": "2025-10-06", + "value": 36 + }, + { + "date": "2025-10-12", + "value": 23 + }, + { + "date": "2025-10-18", + "value": 26 + }, + { + "date": "2025-11-04", + "value": 27 + }, + { + "date": "2025-11-10", + "value": 31 + }, + { + "date": "2025-11-16", + "value": 33 + }, + { + "date": "2025-12-05", + "value": 27 + }, + { + "date": "2025-12-11", + "value": 29 + }, + { + "date": "2025-12-17", + "value": 32 + }, + { + "date": "2026-01-06", + "value": 26 + }, + { + "date": "2026-01-12", + "value": 29 + }, + { + "date": "2026-01-18", + "value": 31 + }, + { + "date": "2026-02-04", + "value": 33 + }, + { + "date": "2026-02-10", + "value": 36 + }, + { + "date": "2026-02-16", + "value": 39 + }, + { + "date": "2026-03-05", + "value": 33 + }, + { + "date": "2026-03-11", + "value": 36 + }, + { + "date": "2026-03-17", + "value": 23 + }, + { + "date": "2026-04-06", + "value": 40 + }, + { + "date": "2026-04-12", + "value": 27 + }, + { + "date": "2026-04-18", + "value": 31 + }, + { + "date": "2026-05-04", + "value": 24 + }, + { + "date": "2026-05-10", + "value": 27 + }, + { + "date": "2026-05-16", + "value": 29 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 35.0, + "median": 35.0, + "p10": 35.0, + "p25": 35.0, + "p75": 35.0, + "p90": 35.0, + "n": 1 + }, + { + "month": "2023-03", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 55.0, + "median": 55.0, + "p10": 55.0, + "p25": 55.0, + "p75": 55.0, + "p90": 55.0, + "n": 1 + }, + { + "month": "2024-05", + "mean": 25.0, + "median": 25.0, + "p10": 25.0, + "p25": 25.0, + "p75": 25.0, + "p90": 25.0, + "n": 1 + }, + { + "month": "2024-08", + "mean": 38.0, + "median": 38.0, + "p10": 38.0, + "p25": 38.0, + "p75": 38.0, + "p90": 38.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 15.0, + "median": 15.0, + "p10": 15.0, + "p25": 15.0, + "p75": 15.0, + "p90": 15.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 32.0, + "median": 32.0, + "p10": 32.0, + "p25": 32.0, + "p75": 32.0, + "p90": 32.0, + "n": 1 + }, + { + "month": "2025-04", + "mean": 28.0, + "median": 28.0, + "p10": 28.0, + "p25": 28.0, + "p75": 28.0, + "p90": 28.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 45.0, + "median": 45.0, + "p10": 45.0, + "p25": 45.0, + "p75": 45.0, + "p90": 45.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 30.0, + "median": 30.0, + "p10": 30.0, + "p25": 30.0, + "p75": 30.0, + "p90": 30.0, + "n": 1 + }, + { + "month": "2025-08", + "mean": 22.0, + "median": 22.0, + "p10": 22.0, + "p25": 22.0, + "p75": 22.0, + "p90": 22.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 34.8, + "median": 37.0, + "p10": 29.0, + "p25": 33.5, + "p75": 38.3, + "p90": 38.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 28.3, + "median": 26.0, + "p10": 23.6, + "p25": 24.5, + "p75": 31.0, + "p90": 34.0, + "n": 3 + }, + { + "month": "2025-11", + "mean": 30.3, + "median": 31.0, + "p10": 27.8, + "p25": 29.0, + "p75": 32.0, + "p90": 32.6, + "n": 3 + }, + { + "month": "2025-12", + "mean": 29.3, + "median": 29.0, + "p10": 27.4, + "p25": 28.0, + "p75": 30.5, + "p90": 31.4, + "n": 3 + }, + { + "month": "2026-01", + "mean": 28.7, + "median": 29.0, + "p10": 26.6, + "p25": 27.5, + "p75": 30.0, + "p90": 30.6, + "n": 3 + }, + { + "month": "2026-02", + "mean": 36.0, + "median": 36.0, + "p10": 33.6, + "p25": 34.5, + "p75": 37.5, + "p90": 38.4, + "n": 3 + }, + { + "month": "2026-03", + "mean": 30.7, + "median": 33.0, + "p10": 25.0, + "p25": 28.0, + "p75": 34.5, + "p90": 35.4, + "n": 3 + }, + { + "month": "2026-04", + "mean": 32.7, + "median": 31.0, + "p10": 27.8, + "p25": 29.0, + "p75": 35.5, + "p90": 38.2, + "n": 3 + }, + { + "month": "2026-05", + "mean": 26.7, + "median": 27.0, + "p10": 24.6, + "p25": 25.5, + "p75": 28.0, + "p90": 28.6, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 45.0, + "median": 44.0, + "std": 14.0, + "min": 10, + "max": 95, + "p25": 36.0, + "p75": 49.0, + "p85": 53.0, + "p95": 67.6 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 28.5, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 42 + }, + { + "date": "2023-05-05", + "value": 65 + }, + { + "date": "2023-05-20", + "value": 28 + }, + { + "date": "2024-01-10", + "value": 95 + }, + { + "date": "2024-01-25", + "value": 35 + }, + { + "date": "2024-08-15", + "value": 10 + }, + { + "date": "2025-02-05", + "value": 78 + }, + { + "date": "2025-02-18", + "value": 55 + }, + { + "date": "2025-08-10", + "value": 42 + }, + { + "date": "2025-08-20", + "value": 32 + }, + { + "date": "2025-09-06", + "value": 39 + }, + { + "date": "2025-09-12", + "value": 42 + }, + { + "date": "2025-09-18", + "value": 46 + }, + { + "date": "2025-10-04", + "value": 49 + }, + { + "date": "2025-10-10", + "value": 53 + }, + { + "date": "2025-10-16", + "value": 57 + }, + { + "date": "2025-11-05", + "value": 48 + }, + { + "date": "2025-11-11", + "value": 52 + }, + { + "date": "2025-11-17", + "value": 34 + }, + { + "date": "2025-12-06", + "value": 48 + }, + { + "date": "2025-12-12", + "value": 30 + }, + { + "date": "2025-12-18", + "value": 34 + }, + { + "date": "2026-01-04", + "value": 36 + }, + { + "date": "2026-01-10", + "value": 41 + }, + { + "date": "2026-01-16", + "value": 43 + }, + { + "date": "2026-02-05", + "value": 36 + }, + { + "date": "2026-02-11", + "value": 39 + }, + { + "date": "2026-02-17", + "value": 42 + }, + { + "date": "2026-03-06", + "value": 46 + }, + { + "date": "2026-03-12", + "value": 49 + }, + { + "date": "2026-03-18", + "value": 53 + }, + { + "date": "2026-04-04", + "value": 45 + }, + { + "date": "2026-04-10", + "value": 48 + }, + { + "date": "2026-04-16", + "value": 52 + }, + { + "date": "2026-05-05", + "value": 44 + }, + { + "date": "2026-05-11", + "value": 48 + }, + { + "date": "2026-05-17", + "value": 30 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 42.0, + "median": 42.0, + "p10": 42.0, + "p25": 42.0, + "p75": 42.0, + "p90": 42.0, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 46.5, + "median": 46.5, + "p10": 31.7, + "p25": 37.3, + "p75": 55.8, + "p90": 61.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 65.0, + "median": 65.0, + "p10": 41.0, + "p25": 50.0, + "p75": 80.0, + "p90": 89.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 10.0, + "median": 10.0, + "p10": 10.0, + "p25": 10.0, + "p75": 10.0, + "p90": 10.0, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 66.5, + "median": 66.5, + "p10": 57.3, + "p25": 60.8, + "p75": 72.3, + "p90": 75.7, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 37.0, + "median": 37.0, + "p10": 33.0, + "p25": 34.5, + "p75": 39.5, + "p90": 41.0, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 42.3, + "median": 42.0, + "p10": 39.6, + "p25": 40.5, + "p75": 44.0, + "p90": 45.2, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 53.0, + "median": 53.0, + "p10": 49.8, + "p25": 51.0, + "p75": 55.0, + "p90": 56.2, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 44.7, + "median": 48.0, + "p10": 36.8, + "p25": 41.0, + "p75": 50.0, + "p90": 51.2, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 37.3, + "median": 34.0, + "p10": 30.8, + "p25": 32.0, + "p75": 41.0, + "p90": 45.2, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 40.0, + "median": 41.0, + "p10": 37.0, + "p25": 38.5, + "p75": 42.0, + "p90": 42.6, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 39.0, + "median": 39.0, + "p10": 36.6, + "p25": 37.5, + "p75": 40.5, + "p90": 41.4, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 49.3, + "median": 49.0, + "p10": 46.6, + "p25": 47.5, + "p75": 51.0, + "p90": 52.2, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 48.3, + "median": 48.0, + "p10": 45.6, + "p25": 46.5, + "p75": 50.0, + "p90": 51.2, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 40.7, + "median": 44.0, + "p10": 32.8, + "p25": 37.0, + "p75": 46.0, + "p90": 47.2, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ] + }, + { + "id": "summit-medium-roast", + "name": "Summit Medium Roast", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 47.4, + "median": 47.2, + "std": 15.7, + "min": 9.4, + "max": 123.9, + "p25": 41.3, + "p75": 53.1, + "p85": 56.6, + "p95": 65.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 64.9 + }, + { + "date": "2022-06-10", + "value": 49.6 + }, + { + "date": "2022-09-22", + "value": 9.4 + }, + { + "date": "2022-12-05", + "value": 74.3 + }, + { + "date": "2023-02-14", + "value": 44.8 + }, + { + "date": "2023-05-30", + "value": 26.0 + }, + { + "date": "2023-08-17", + "value": 83.8 + }, + { + "date": "2023-11-02", + "value": 35.4 + }, + { + "date": "2024-01-25", + "value": 53.1 + }, + { + "date": "2024-04-11", + "value": 21.2 + }, + { + "date": "2024-07-09", + "value": 123.9 + }, + { + "date": "2024-10-03", + "value": 41.3 + }, + { + "date": "2025-01-20", + "value": 14.2 + }, + { + "date": "2025-04-08", + "value": 56.6 + }, + { + "date": "2025-09-05", + "value": 46.0 + }, + { + "date": "2025-09-11", + "value": 48.4 + }, + { + "date": "2025-09-17", + "value": 51.9 + }, + { + "date": "2025-09-23", + "value": 56.6 + }, + { + "date": "2025-09-29", + "value": 60.2 + }, + { + "date": "2025-10-06", + "value": 43.7 + }, + { + "date": "2025-10-12", + "value": 47.2 + }, + { + "date": "2025-10-18", + "value": 51.9 + }, + { + "date": "2025-10-24", + "value": 55.5 + }, + { + "date": "2025-10-30", + "value": 36.6 + }, + { + "date": "2025-11-04", + "value": 42.5 + }, + { + "date": "2025-11-10", + "value": 47.2 + }, + { + "date": "2025-11-16", + "value": 50.7 + }, + { + "date": "2025-11-22", + "value": 31.9 + }, + { + "date": "2025-11-28", + "value": 36.6 + }, + { + "date": "2025-12-05", + "value": 54.3 + }, + { + "date": "2025-12-11", + "value": 57.8 + }, + { + "date": "2025-12-17", + "value": 38.9 + }, + { + "date": "2025-12-23", + "value": 43.7 + }, + { + "date": "2025-12-29", + "value": 46.0 + }, + { + "date": "2026-01-06", + "value": 53.1 + }, + { + "date": "2026-01-12", + "value": 34.2 + }, + { + "date": "2026-01-18", + "value": 38.9 + }, + { + "date": "2026-01-24", + "value": 41.3 + }, + { + "date": "2026-01-30", + "value": 44.8 + }, + { + "date": "2026-02-04", + "value": 41.3 + }, + { + "date": "2026-02-10", + "value": 46.0 + }, + { + "date": "2026-02-16", + "value": 48.4 + }, + { + "date": "2026-02-22", + "value": 51.9 + }, + { + "date": "2026-02-28", + "value": 56.6 + }, + { + "date": "2026-03-05", + "value": 41.3 + }, + { + "date": "2026-03-11", + "value": 43.7 + }, + { + "date": "2026-03-17", + "value": 47.2 + }, + { + "date": "2026-03-23", + "value": 51.9 + }, + { + "date": "2026-03-29", + "value": 55.5 + }, + { + "date": "2026-04-06", + "value": 38.9 + }, + { + "date": "2026-04-12", + "value": 42.5 + }, + { + "date": "2026-04-18", + "value": 47.2 + }, + { + "date": "2026-04-24", + "value": 50.7 + }, + { + "date": "2026-04-30", + "value": 31.9 + }, + { + "date": "2026-05-04", + "value": 49.6 + }, + { + "date": "2026-05-10", + "value": 54.3 + }, + { + "date": "2026-05-16", + "value": 57.8 + }, + { + "date": "2026-05-22", + "value": 38.9 + }, + { + "date": "2026-05-28", + "value": 43.7 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2022-06", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1 + }, + { + "month": "2022-09", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2022-12", + "mean": 74.3, + "median": 74.3, + "p10": 74.3, + "p25": 74.3, + "p75": 74.3, + "p90": 74.3, + "n": 1 + }, + { + "month": "2023-02", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 83.8, + "median": 83.8, + "p10": 83.8, + "p25": 83.8, + "p75": 83.8, + "p90": 83.8, + "n": 1 + }, + { + "month": "2023-11", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2024-01", + "mean": 53.1, + "median": 53.1, + "p10": 53.1, + "p25": 53.1, + "p75": 53.1, + "p90": 53.1, + "n": 1 + }, + { + "month": "2024-04", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2024-07", + "mean": 123.9, + "median": 123.9, + "p10": 123.9, + "p25": 123.9, + "p75": 123.9, + "p90": 123.9, + "n": 1 + }, + { + "month": "2024-10", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2025-09", + "mean": 52.6, + "median": 51.9, + "p10": 47.0, + "p25": 48.4, + "p75": 56.6, + "p90": 58.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 47.0, + "median": 47.2, + "p10": 39.4, + "p25": 43.7, + "p75": 51.9, + "p90": 54.0, + "n": 5 + }, + { + "month": "2025-11", + "mean": 41.8, + "median": 42.5, + "p10": 33.7, + "p25": 36.6, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2025-12", + "mean": 48.1, + "median": 46.0, + "p10": 40.8, + "p25": 43.7, + "p75": 54.3, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-01", + "mean": 42.5, + "median": 41.3, + "p10": 36.1, + "p25": 38.9, + "p75": 44.8, + "p90": 49.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 48.9, + "median": 48.4, + "p10": 43.2, + "p25": 46.0, + "p75": 51.9, + "p90": 54.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 47.9, + "median": 47.2, + "p10": 42.2, + "p25": 43.7, + "p75": 51.9, + "p90": 54.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 42.2, + "median": 42.5, + "p10": 34.7, + "p25": 38.9, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 48.9, + "median": 49.6, + "p10": 40.8, + "p25": 43.7, + "p75": 54.3, + "p90": 56.4, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 39.4, + "median": 38.9, + "std": 13.5, + "min": 5.9, + "max": 96.8, + "p25": 33.0, + "p75": 44.8, + "p85": 48.0, + "p95": 60.9 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 37.8 + }, + { + "date": "2022-04-19", + "value": 56.6 + }, + { + "date": "2022-07-11", + "value": 5.9 + }, + { + "date": "2022-09-28", + "value": 79.1 + }, + { + "date": "2022-12-15", + "value": 29.5 + }, + { + "date": "2023-03-07", + "value": 48.4 + }, + { + "date": "2023-05-22", + "value": 17.7 + }, + { + "date": "2023-08-09", + "value": 96.8 + }, + { + "date": "2023-10-30", + "value": 44.8 + }, + { + "date": "2024-01-16", + "value": 23.6 + }, + { + "date": "2024-03-25", + "value": 61.4 + }, + { + "date": "2024-06-12", + "value": 11.8 + }, + { + "date": "2024-08-28", + "value": 51.9 + }, + { + "date": "2024-11-14", + "value": 33.0 + }, + { + "date": "2025-01-06", + "value": 41.3 + }, + { + "date": "2025-03-18", + "value": 21.2 + }, + { + "date": "2025-05-29", + "value": 64.9 + }, + { + "date": "2025-08-12", + "value": 30.7 + }, + { + "date": "2025-09-04", + "value": 30.7 + }, + { + "date": "2025-09-10", + "value": 34.2 + }, + { + "date": "2025-09-16", + "value": 36.6 + }, + { + "date": "2025-09-22", + "value": 40.1 + }, + { + "date": "2025-09-28", + "value": 43.7 + }, + { + "date": "2025-10-05", + "value": 30.7 + }, + { + "date": "2025-10-11", + "value": 33.0 + }, + { + "date": "2025-10-17", + "value": 36.6 + }, + { + "date": "2025-10-23", + "value": 38.9 + }, + { + "date": "2025-10-29", + "value": 42.5 + }, + { + "date": "2025-11-06", + "value": 38.9 + }, + { + "date": "2025-11-12", + "value": 42.5 + }, + { + "date": "2025-11-18", + "value": 44.8 + }, + { + "date": "2025-11-24", + "value": 49.6 + }, + { + "date": "2025-11-30", + "value": 33.0 + }, + { + "date": "2025-12-04", + "value": 37.8 + }, + { + "date": "2025-12-10", + "value": 41.3 + }, + { + "date": "2025-12-16", + "value": 44.8 + }, + { + "date": "2025-12-22", + "value": 28.3 + }, + { + "date": "2025-12-28", + "value": 33.0 + }, + { + "date": "2026-01-05", + "value": 47.2 + }, + { + "date": "2026-01-11", + "value": 50.7 + }, + { + "date": "2026-01-17", + "value": 34.2 + }, + { + "date": "2026-01-23", + "value": 38.9 + }, + { + "date": "2026-01-29", + "value": 41.3 + }, + { + "date": "2026-02-06", + "value": 47.2 + }, + { + "date": "2026-02-12", + "value": 30.7 + }, + { + "date": "2026-02-18", + "value": 34.2 + }, + { + "date": "2026-02-24", + "value": 36.6 + }, + { + "date": "2026-02-30", + "value": 40.1 + }, + { + "date": "2026-03-04", + "value": 26.0 + }, + { + "date": "2026-03-10", + "value": 30.7 + }, + { + "date": "2026-03-16", + "value": 33.0 + }, + { + "date": "2026-03-22", + "value": 36.6 + }, + { + "date": "2026-03-28", + "value": 38.9 + }, + { + "date": "2026-04-05", + "value": 36.6 + }, + { + "date": "2026-04-11", + "value": 38.9 + }, + { + "date": "2026-04-17", + "value": 42.5 + }, + { + "date": "2026-04-23", + "value": 44.8 + }, + { + "date": "2026-04-29", + "value": 49.6 + }, + { + "date": "2026-05-06", + "value": 35.4 + }, + { + "date": "2026-05-12", + "value": 37.8 + }, + { + "date": "2026-05-18", + "value": 41.3 + }, + { + "date": "2026-05-24", + "value": 44.8 + }, + { + "date": "2026-05-30", + "value": 28.3 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2022-04", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-09", + "mean": 79.1, + "median": 79.1, + "p10": 79.1, + "p25": 79.1, + "p75": 79.1, + "p90": 79.1, + "n": 1 + }, + { + "month": "2022-12", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 48.4, + "median": 48.4, + "p10": 48.4, + "p25": 48.4, + "p75": 48.4, + "p90": 48.4, + "n": 1 + }, + { + "month": "2023-05", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2023-08", + "mean": 96.8, + "median": 96.8, + "p10": 96.8, + "p25": 96.8, + "p75": 96.8, + "p90": 96.8, + "n": 1 + }, + { + "month": "2023-10", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 23.6, + "median": 23.6, + "p10": 23.6, + "p25": 23.6, + "p75": 23.6, + "p90": 23.6, + "n": 1 + }, + { + "month": "2024-03", + "mean": 61.4, + "median": 61.4, + "p10": 61.4, + "p25": 61.4, + "p75": 61.4, + "p90": 61.4, + "n": 1 + }, + { + "month": "2024-06", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1 + }, + { + "month": "2024-08", + "mean": 51.9, + "median": 51.9, + "p10": 51.9, + "p25": 51.9, + "p75": 51.9, + "p90": 51.9, + "n": 1 + }, + { + "month": "2024-11", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2025-03", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2025-05", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2025-08", + "mean": 30.7, + "median": 30.7, + "p10": 30.7, + "p25": 30.7, + "p75": 30.7, + "p90": 30.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 37.1, + "median": 36.6, + "p10": 32.1, + "p25": 34.2, + "p75": 40.1, + "p90": 42.2, + "n": 5 + }, + { + "month": "2025-10", + "mean": 36.3, + "median": 36.6, + "p10": 31.6, + "p25": 33.0, + "p75": 38.9, + "p90": 41.1, + "n": 5 + }, + { + "month": "2025-11", + "mean": 41.8, + "median": 42.5, + "p10": 35.4, + "p25": 38.9, + "p75": 44.8, + "p90": 47.7, + "n": 5 + }, + { + "month": "2025-12", + "mean": 37.1, + "median": 37.8, + "p10": 30.2, + "p25": 33.0, + "p75": 41.3, + "p90": 43.4, + "n": 5 + }, + { + "month": "2026-01", + "mean": 42.5, + "median": 41.3, + "p10": 36.1, + "p25": 38.9, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2026-02", + "mean": 37.8, + "median": 36.6, + "p10": 32.1, + "p25": 34.2, + "p75": 40.1, + "p90": 44.4, + "n": 5 + }, + { + "month": "2026-03", + "mean": 33.0, + "median": 33.0, + "p10": 27.8, + "p25": 30.7, + "p75": 36.6, + "p90": 38.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 42.5, + "median": 42.5, + "p10": 37.5, + "p25": 38.9, + "p75": 44.8, + "p90": 47.7, + "n": 5 + }, + { + "month": "2026-05", + "mean": 37.5, + "median": 37.8, + "p10": 31.2, + "p25": 35.4, + "p75": 41.3, + "p90": 43.4, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 30.8, + "median": 29.5, + "std": 9.4, + "min": 8.3, + "max": 73.2, + "p25": 26.5, + "p75": 34.2, + "p85": 35.4, + "p95": 43.1 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 41.3 + }, + { + "date": "2022-10-18", + "value": 18.9 + }, + { + "date": "2023-01-24", + "value": 73.2 + }, + { + "date": "2023-06-15", + "value": 8.3 + }, + { + "date": "2023-09-28", + "value": 47.2 + }, + { + "date": "2024-02-12", + "value": 29.5 + }, + { + "date": "2024-05-07", + "value": 56.6 + }, + { + "date": "2024-09-19", + "value": 14.2 + }, + { + "date": "2025-02-04", + "value": 35.4 + }, + { + "date": "2025-06-10", + "value": 16.5 + }, + { + "date": "2025-09-06", + "value": 35.4 + }, + { + "date": "2025-09-12", + "value": 22.4 + }, + { + "date": "2025-09-18", + "value": 26.0 + }, + { + "date": "2025-09-24", + "value": 27.1 + }, + { + "date": "2025-09-30", + "value": 29.5 + }, + { + "date": "2025-10-04", + "value": 27.1 + }, + { + "date": "2025-10-10", + "value": 29.5 + }, + { + "date": "2025-10-16", + "value": 31.9 + }, + { + "date": "2025-10-22", + "value": 34.2 + }, + { + "date": "2025-10-28", + "value": 36.6 + }, + { + "date": "2025-11-05", + "value": 27.1 + }, + { + "date": "2025-11-11", + "value": 29.5 + }, + { + "date": "2025-11-17", + "value": 31.9 + }, + { + "date": "2025-11-23", + "value": 34.2 + }, + { + "date": "2025-11-29", + "value": 36.6 + }, + { + "date": "2025-12-06", + "value": 26.0 + }, + { + "date": "2025-12-12", + "value": 28.3 + }, + { + "date": "2025-12-18", + "value": 30.7 + }, + { + "date": "2025-12-24", + "value": 33.0 + }, + { + "date": "2025-12-30", + "value": 21.2 + }, + { + "date": "2026-01-04", + "value": 33.0 + }, + { + "date": "2026-01-10", + "value": 35.4 + }, + { + "date": "2026-01-16", + "value": 37.8 + }, + { + "date": "2026-01-22", + "value": 26.0 + }, + { + "date": "2026-01-28", + "value": 28.3 + }, + { + "date": "2026-02-05", + "value": 31.9 + }, + { + "date": "2026-02-11", + "value": 35.4 + }, + { + "date": "2026-02-17", + "value": 22.4 + }, + { + "date": "2026-02-23", + "value": 26.0 + }, + { + "date": "2026-02-29", + "value": 27.1 + }, + { + "date": "2026-03-06", + "value": 40.1 + }, + { + "date": "2026-03-12", + "value": 27.1 + }, + { + "date": "2026-03-18", + "value": 29.5 + }, + { + "date": "2026-03-24", + "value": 31.9 + }, + { + "date": "2026-03-30", + "value": 34.2 + }, + { + "date": "2026-04-04", + "value": 23.6 + }, + { + "date": "2026-04-10", + "value": 27.1 + }, + { + "date": "2026-04-16", + "value": 29.5 + }, + { + "date": "2026-04-22", + "value": 31.9 + }, + { + "date": "2026-04-28", + "value": 34.2 + }, + { + "date": "2026-05-05", + "value": 23.6 + }, + { + "date": "2026-05-11", + "value": 26.0 + }, + { + "date": "2026-05-17", + "value": 28.3 + }, + { + "date": "2026-05-23", + "value": 30.7 + }, + { + "date": "2026-05-29", + "value": 33.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2022-10", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2023-01", + "mean": 73.2, + "median": 73.2, + "p10": 73.2, + "p25": 73.2, + "p75": 73.2, + "p90": 73.2, + "n": 1 + }, + { + "month": "2023-06", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-09", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2024-02", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2024-09", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2025-02", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2025-06", + "mean": 16.5, + "median": 16.5, + "p10": 16.5, + "p25": 16.5, + "p75": 16.5, + "p90": 16.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 28.1, + "median": 27.1, + "p10": 23.8, + "p25": 26.0, + "p75": 29.5, + "p90": 33.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 31.9, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 35.6, + "n": 5 + }, + { + "month": "2025-11", + "mean": 31.9, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 35.6, + "n": 5 + }, + { + "month": "2025-12", + "mean": 27.8, + "median": 28.3, + "p10": 23.1, + "p25": 26.0, + "p75": 30.7, + "p90": 32.1, + "n": 5 + }, + { + "month": "2026-01", + "mean": 32.1, + "median": 33.0, + "p10": 26.9, + "p25": 28.3, + "p75": 35.4, + "p90": 36.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 28.6, + "median": 27.1, + "p10": 23.8, + "p25": 26.0, + "p75": 31.9, + "p90": 34.0, + "n": 5 + }, + { + "month": "2026-03", + "mean": 32.6, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 37.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.3, + "median": 29.5, + "p10": 25.0, + "p25": 27.1, + "p75": 31.9, + "p90": 33.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 28.3, + "median": 28.3, + "p10": 24.5, + "p25": 26.0, + "p75": 30.7, + "p90": 32.1, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 57.0, + "median": 54.3, + "std": 23.4, + "min": 5.9, + "max": 153.4, + "p25": 45.4, + "p75": 64.3, + "p85": 72.0, + "p95": 103.5 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 3.776, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 41.3 + }, + { + "date": "2022-04-15", + "value": 73.2 + }, + { + "date": "2022-04-28", + "value": 21.2 + }, + { + "date": "2022-08-05", + "value": 103.8 + }, + { + "date": "2022-08-12", + "value": 49.6 + }, + { + "date": "2022-08-20", + "value": 64.9 + }, + { + "date": "2022-08-28", + "value": 35.4 + }, + { + "date": "2023-01-10", + "value": 85.0 + }, + { + "date": "2023-01-22", + "value": 29.5 + }, + { + "date": "2023-01-30", + "value": 56.6 + }, + { + "date": "2023-06-05", + "value": 17.7 + }, + { + "date": "2023-06-18", + "value": 112.1 + }, + { + "date": "2023-10-03", + "value": 153.4 + }, + { + "date": "2023-10-10", + "value": 53.1 + }, + { + "date": "2023-10-18", + "value": 44.8 + }, + { + "date": "2023-10-25", + "value": 76.7 + }, + { + "date": "2023-10-30", + "value": 26.0 + }, + { + "date": "2024-03-05", + "value": 92.0 + }, + { + "date": "2024-03-12", + "value": 5.9 + }, + { + "date": "2024-03-20", + "value": 64.9 + }, + { + "date": "2024-03-28", + "value": 47.2 + }, + { + "date": "2024-07-08", + "value": 33.0 + }, + { + "date": "2024-07-15", + "value": 100.3 + }, + { + "date": "2024-07-22", + "value": 59.0 + }, + { + "date": "2024-11-04", + "value": 129.8 + }, + { + "date": "2024-11-11", + "value": 37.8 + }, + { + "date": "2024-11-18", + "value": 80.2 + }, + { + "date": "2024-11-25", + "value": 53.1 + }, + { + "date": "2024-11-30", + "value": 108.6 + }, + { + "date": "2025-03-03", + "value": 23.6 + }, + { + "date": "2025-03-10", + "value": 68.4 + }, + { + "date": "2025-03-17", + "value": 41.3 + }, + { + "date": "2025-03-24", + "value": 49.6 + }, + { + "date": "2025-07-02", + "value": 88.5 + }, + { + "date": "2025-07-09", + "value": 14.2 + }, + { + "date": "2025-07-16", + "value": 56.6 + }, + { + "date": "2025-07-23", + "value": 70.8 + }, + { + "date": "2025-07-30", + "value": 44.8 + }, + { + "date": "2025-09-05", + "value": 57.8 + }, + { + "date": "2025-09-11", + "value": 63.7 + }, + { + "date": "2025-09-17", + "value": 40.1 + }, + { + "date": "2025-09-23", + "value": 46.0 + }, + { + "date": "2025-09-29", + "value": 49.6 + }, + { + "date": "2025-10-06", + "value": 72.0 + }, + { + "date": "2025-10-12", + "value": 48.4 + }, + { + "date": "2025-10-18", + "value": 54.3 + }, + { + "date": "2025-10-24", + "value": 57.8 + }, + { + "date": "2025-10-30", + "value": 62.5 + }, + { + "date": "2025-11-04", + "value": 42.5 + }, + { + "date": "2025-11-10", + "value": 48.4 + }, + { + "date": "2025-11-16", + "value": 51.9 + }, + { + "date": "2025-11-22", + "value": 56.6 + }, + { + "date": "2025-11-28", + "value": 61.4 + }, + { + "date": "2025-12-05", + "value": 42.5 + }, + { + "date": "2025-12-11", + "value": 46.0 + }, + { + "date": "2025-12-17", + "value": 50.7 + }, + { + "date": "2025-12-23", + "value": 55.5 + }, + { + "date": "2025-12-29", + "value": 60.2 + }, + { + "date": "2026-01-06", + "value": 55.5 + }, + { + "date": "2026-01-12", + "value": 59.0 + }, + { + "date": "2026-01-18", + "value": 63.7 + }, + { + "date": "2026-01-24", + "value": 68.4 + }, + { + "date": "2026-01-30", + "value": 46.0 + }, + { + "date": "2026-02-04", + "value": 53.1 + }, + { + "date": "2026-02-10", + "value": 57.8 + }, + { + "date": "2026-02-16", + "value": 63.7 + }, + { + "date": "2026-02-22", + "value": 40.1 + }, + { + "date": "2026-02-28", + "value": 46.0 + }, + { + "date": "2026-03-05", + "value": 66.1 + }, + { + "date": "2026-03-11", + "value": 72.0 + }, + { + "date": "2026-03-17", + "value": 48.4 + }, + { + "date": "2026-03-23", + "value": 54.3 + }, + { + "date": "2026-03-29", + "value": 57.8 + }, + { + "date": "2026-04-06", + "value": 66.1 + }, + { + "date": "2026-04-12", + "value": 42.5 + }, + { + "date": "2026-04-18", + "value": 48.4 + }, + { + "date": "2026-04-24", + "value": 51.9 + }, + { + "date": "2026-04-30", + "value": 56.6 + }, + { + "date": "2026-05-04", + "value": 37.8 + }, + { + "date": "2026-05-10", + "value": 42.5 + }, + { + "date": "2026-05-16", + "value": 46.0 + }, + { + "date": "2026-05-22", + "value": 50.7 + }, + { + "date": "2026-05-28", + "value": 55.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 45.2, + "median": 41.3, + "p10": 25.3, + "p25": 31.3, + "p75": 57.2, + "p90": 66.8, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 63.5, + "median": 57.2, + "p10": 39.6, + "p25": 46.0, + "p75": 74.7, + "p90": 92.2, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 57.0, + "median": 56.6, + "p10": 34.9, + "p25": 43.1, + "p75": 70.8, + "p90": 79.3, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 64.9, + "median": 64.9, + "p10": 27.1, + "p25": 41.3, + "p75": 88.5, + "p90": 102.7, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 70.8, + "median": 53.1, + "p10": 33.5, + "p25": 44.8, + "p75": 76.7, + "p90": 122.7, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 52.5, + "median": 56.0, + "p10": 18.3, + "p25": 36.9, + "p75": 71.7, + "p90": 83.9, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 64.1, + "median": 59.0, + "p10": 38.2, + "p25": 46.0, + "p75": 79.6, + "p90": 92.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 81.9, + "median": 80.2, + "p10": 43.9, + "p25": 53.1, + "p75": 108.6, + "p90": 121.3, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 45.8, + "median": 45.4, + "p10": 28.9, + "p25": 36.9, + "p75": 54.3, + "p90": 62.8, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 55.0, + "median": 56.6, + "p10": 26.4, + "p25": 44.8, + "p75": 70.8, + "p90": 81.4, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 51.4, + "median": 49.6, + "p10": 42.5, + "p25": 46.0, + "p75": 57.8, + "p90": 61.4, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 59.0, + "median": 57.8, + "p10": 50.7, + "p25": 54.3, + "p75": 62.5, + "p90": 68.2, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 52.2, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 51.0, + "median": 50.7, + "p10": 43.9, + "p25": 46.0, + "p75": 55.5, + "p90": 58.3, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 58.5, + "median": 59.0, + "p10": 49.8, + "p25": 55.5, + "p75": 63.7, + "p90": 66.6, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 52.2, + "median": 53.1, + "p10": 42.5, + "p25": 46.0, + "p75": 57.8, + "p90": 61.4, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 59.7, + "median": 57.8, + "p10": 50.7, + "p25": 54.3, + "p75": 66.1, + "p90": 69.6, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 53.1, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 56.6, + "p90": 62.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 46.5, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 50.7, + "p90": 53.6, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 43.2, + "median": 40.1, + "std": 18.6, + "min": 3.5, + "max": 115.6, + "p25": 33.0, + "p75": 48.4, + "p85": 53.1, + "p95": 81.7 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 2.124, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 33.0 + }, + { + "date": "2022-05-10", + "value": 53.1 + }, + { + "date": "2022-05-18", + "value": 14.2 + }, + { + "date": "2022-05-25", + "value": 73.2 + }, + { + "date": "2023-02-06", + "value": 38.9 + }, + { + "date": "2023-02-14", + "value": 92.0 + }, + { + "date": "2023-02-22", + "value": 23.6 + }, + { + "date": "2023-02-28", + "value": 64.9 + }, + { + "date": "2023-09-05", + "value": 9.4 + }, + { + "date": "2023-09-15", + "value": 49.6 + }, + { + "date": "2023-09-25", + "value": 76.7 + }, + { + "date": "2024-04-03", + "value": 44.8 + }, + { + "date": "2024-04-10", + "value": 17.7 + }, + { + "date": "2024-04-17", + "value": 85.0 + }, + { + "date": "2024-04-24", + "value": 29.5 + }, + { + "date": "2024-10-02", + "value": 56.6 + }, + { + "date": "2024-10-09", + "value": 3.5 + }, + { + "date": "2024-10-16", + "value": 100.3 + }, + { + "date": "2024-10-23", + "value": 35.4 + }, + { + "date": "2024-10-30", + "value": 64.9 + }, + { + "date": "2025-04-07", + "value": 26.0 + }, + { + "date": "2025-04-14", + "value": 47.2 + }, + { + "date": "2025-04-21", + "value": 115.6 + }, + { + "date": "2025-04-28", + "value": 21.2 + }, + { + "date": "2025-09-04", + "value": 46.0 + }, + { + "date": "2025-09-10", + "value": 48.4 + }, + { + "date": "2025-09-16", + "value": 53.1 + }, + { + "date": "2025-09-22", + "value": 35.4 + }, + { + "date": "2025-09-28", + "value": 40.1 + }, + { + "date": "2025-10-05", + "value": 44.8 + }, + { + "date": "2025-10-11", + "value": 48.4 + }, + { + "date": "2025-10-17", + "value": 31.9 + }, + { + "date": "2025-10-23", + "value": 35.4 + }, + { + "date": "2025-10-29", + "value": 37.8 + }, + { + "date": "2025-11-06", + "value": 44.8 + }, + { + "date": "2025-11-12", + "value": 27.1 + }, + { + "date": "2025-11-18", + "value": 31.9 + }, + { + "date": "2025-11-24", + "value": 34.2 + }, + { + "date": "2025-11-30", + "value": 37.8 + }, + { + "date": "2025-12-04", + "value": 33.0 + }, + { + "date": "2025-12-10", + "value": 37.8 + }, + { + "date": "2025-12-16", + "value": 40.1 + }, + { + "date": "2025-12-22", + "value": 43.7 + }, + { + "date": "2025-12-28", + "value": 47.2 + }, + { + "date": "2026-01-05", + "value": 33.0 + }, + { + "date": "2026-01-11", + "value": 36.6 + }, + { + "date": "2026-01-17", + "value": 38.9 + }, + { + "date": "2026-01-23", + "value": 42.5 + }, + { + "date": "2026-01-29", + "value": 46.0 + }, + { + "date": "2026-02-06", + "value": 42.5 + }, + { + "date": "2026-02-12", + "value": 46.0 + }, + { + "date": "2026-02-18", + "value": 48.4 + }, + { + "date": "2026-02-24", + "value": 53.1 + }, + { + "date": "2026-02-30", + "value": 35.4 + }, + { + "date": "2026-03-04", + "value": 41.3 + }, + { + "date": "2026-03-10", + "value": 44.8 + }, + { + "date": "2026-03-16", + "value": 48.4 + }, + { + "date": "2026-03-22", + "value": 31.9 + }, + { + "date": "2026-03-28", + "value": 35.4 + }, + { + "date": "2026-04-05", + "value": 40.1 + }, + { + "date": "2026-04-11", + "value": 44.8 + }, + { + "date": "2026-04-17", + "value": 27.1 + }, + { + "date": "2026-04-23", + "value": 31.9 + }, + { + "date": "2026-04-29", + "value": 34.2 + }, + { + "date": "2026-05-06", + "value": 50.7 + }, + { + "date": "2026-05-12", + "value": 33.0 + }, + { + "date": "2026-05-18", + "value": 37.8 + }, + { + "date": "2026-05-24", + "value": 40.1 + }, + { + "date": "2026-05-30", + "value": 43.7 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 43.4, + "median": 43.1, + "p10": 19.8, + "p25": 28.3, + "p75": 58.2, + "p90": 67.1, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 54.9, + "median": 51.9, + "p10": 28.2, + "p25": 35.2, + "p75": 71.7, + "p90": 83.9, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 45.2, + "median": 49.6, + "p10": 17.5, + "p25": 29.5, + "p75": 63.1, + "p90": 71.3, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 44.2, + "median": 37.2, + "p10": 21.2, + "p25": 26.5, + "p75": 54.9, + "p90": 72.9, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 52.2, + "median": 56.6, + "p10": 16.3, + "p25": 35.4, + "p75": 64.9, + "p90": 86.1, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 52.5, + "median": 36.6, + "p10": 22.7, + "p25": 24.8, + "p75": 64.3, + "p90": 95.1, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 44.6, + "median": 46.0, + "p10": 37.3, + "p25": 40.1, + "p75": 48.4, + "p90": 51.2, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 39.6, + "median": 37.8, + "p10": 33.3, + "p25": 35.4, + "p75": 44.8, + "p90": 47.0, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 35.2, + "median": 34.2, + "p10": 29.0, + "p25": 31.9, + "p75": 37.8, + "p90": 42.0, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 40.4, + "median": 40.1, + "p10": 34.9, + "p25": 37.8, + "p75": 43.7, + "p90": 45.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 39.4, + "median": 38.9, + "p10": 34.5, + "p25": 36.6, + "p75": 42.5, + "p90": 44.6, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 45.1, + "median": 46.0, + "p10": 38.2, + "p25": 42.5, + "p75": 48.4, + "p90": 51.2, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 40.4, + "median": 41.3, + "p10": 33.3, + "p25": 35.4, + "p75": 44.8, + "p90": 47.0, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 35.6, + "median": 34.2, + "p10": 29.0, + "p25": 31.9, + "p75": 40.1, + "p90": 43.0, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 41.1, + "median": 40.1, + "p10": 34.9, + "p25": 37.8, + "p75": 43.7, + "p90": 47.9, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 51.8, + "median": 48.4, + "std": 22.5, + "min": 4.7, + "max": 135.7, + "p25": 40.5, + "p75": 59.0, + "p85": 63.7, + "p95": 96.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 6.49, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 47.2 + }, + { + "date": "2022-06-15", + "value": 26.0 + }, + { + "date": "2022-06-25", + "value": 80.2 + }, + { + "date": "2023-03-08", + "value": 4.7 + }, + { + "date": "2023-03-15", + "value": 64.9 + }, + { + "date": "2023-03-22", + "value": 135.7 + }, + { + "date": "2023-03-29", + "value": 35.4 + }, + { + "date": "2023-11-06", + "value": 73.2 + }, + { + "date": "2023-11-13", + "value": 21.2 + }, + { + "date": "2023-11-20", + "value": 100.3 + }, + { + "date": "2024-06-03", + "value": 41.3 + }, + { + "date": "2024-06-10", + "value": 85.0 + }, + { + "date": "2024-06-17", + "value": 11.8 + }, + { + "date": "2024-06-24", + "value": 56.6 + }, + { + "date": "2024-06-30", + "value": 112.1 + }, + { + "date": "2025-01-07", + "value": 33.0 + }, + { + "date": "2025-01-14", + "value": 61.4 + }, + { + "date": "2025-01-21", + "value": 17.7 + }, + { + "date": "2025-01-28", + "value": 92.0 + }, + { + "date": "2025-08-04", + "value": 49.6 + }, + { + "date": "2025-08-08", + "value": 9.4 + }, + { + "date": "2025-08-12", + "value": 76.7 + }, + { + "date": "2025-08-16", + "value": 38.9 + }, + { + "date": "2025-08-20", + "value": 118.0 + }, + { + "date": "2025-08-24", + "value": 23.6 + }, + { + "date": "2025-09-06", + "value": 48.4 + }, + { + "date": "2025-09-12", + "value": 53.1 + }, + { + "date": "2025-09-18", + "value": 56.6 + }, + { + "date": "2025-09-24", + "value": 61.4 + }, + { + "date": "2025-09-30", + "value": 40.1 + }, + { + "date": "2025-10-04", + "value": 47.2 + }, + { + "date": "2025-10-10", + "value": 51.9 + }, + { + "date": "2025-10-16", + "value": 56.6 + }, + { + "date": "2025-10-22", + "value": 35.4 + }, + { + "date": "2025-10-28", + "value": 40.1 + }, + { + "date": "2025-11-05", + "value": 59.0 + }, + { + "date": "2025-11-11", + "value": 63.7 + }, + { + "date": "2025-11-17", + "value": 42.5 + }, + { + "date": "2025-11-23", + "value": 48.4 + }, + { + "date": "2025-11-29", + "value": 51.9 + }, + { + "date": "2025-12-06", + "value": 59.0 + }, + { + "date": "2025-12-12", + "value": 37.8 + }, + { + "date": "2025-12-18", + "value": 42.5 + }, + { + "date": "2025-12-24", + "value": 46.0 + }, + { + "date": "2025-12-30", + "value": 50.7 + }, + { + "date": "2026-01-04", + "value": 33.0 + }, + { + "date": "2026-01-10", + "value": 37.8 + }, + { + "date": "2026-01-16", + "value": 41.3 + }, + { + "date": "2026-01-22", + "value": 44.8 + }, + { + "date": "2026-01-28", + "value": 49.6 + }, + { + "date": "2026-02-05", + "value": 46.0 + }, + { + "date": "2026-02-11", + "value": 48.4 + }, + { + "date": "2026-02-17", + "value": 53.1 + }, + { + "date": "2026-02-23", + "value": 56.6 + }, + { + "date": "2026-02-29", + "value": 61.4 + }, + { + "date": "2026-03-06", + "value": 43.7 + }, + { + "date": "2026-03-12", + "value": 47.2 + }, + { + "date": "2026-03-18", + "value": 51.9 + }, + { + "date": "2026-03-24", + "value": 56.6 + }, + { + "date": "2026-03-30", + "value": 35.4 + }, + { + "date": "2026-04-04", + "value": 55.5 + }, + { + "date": "2026-04-10", + "value": 59.0 + }, + { + "date": "2026-04-16", + "value": 63.7 + }, + { + "date": "2026-04-22", + "value": 42.5 + }, + { + "date": "2026-04-28", + "value": 48.4 + }, + { + "date": "2026-05-05", + "value": 54.3 + }, + { + "date": "2026-05-11", + "value": 59.0 + }, + { + "date": "2026-05-17", + "value": 37.8 + }, + { + "date": "2026-05-23", + "value": 42.5 + }, + { + "date": "2026-05-29", + "value": 46.0 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 51.1, + "median": 47.2, + "p10": 30.2, + "p25": 36.6, + "p75": 63.7, + "p90": 73.6, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 60.2, + "median": 50.1, + "p10": 13.9, + "p25": 27.7, + "p75": 82.6, + "p90": 114.5, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 64.9, + "median": 73.2, + "p10": 31.6, + "p25": 47.2, + "p75": 86.7, + "p90": 94.9, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 61.4, + "median": 56.6, + "p10": 23.6, + "p25": 41.3, + "p75": 85.0, + "p90": 101.2, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 51.1, + "median": 47.2, + "p10": 22.3, + "p25": 29.3, + "p75": 69.0, + "p90": 82.8, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 52.7, + "median": 44.2, + "p10": 16.5, + "p25": 27.5, + "p75": 70.0, + "p90": 97.3, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 51.9, + "median": 53.1, + "p10": 43.4, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 46.3, + "median": 47.2, + "p10": 37.3, + "p25": 40.1, + "p75": 51.9, + "p90": 54.8, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 53.1, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 59.0, + "p90": 61.8, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 47.2, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 50.7, + "p90": 55.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 41.3, + "median": 41.3, + "p10": 34.9, + "p25": 37.8, + "p75": 44.8, + "p90": 47.7, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 53.1, + "median": 53.1, + "p10": 47.0, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 47.0, + "median": 47.2, + "p10": 38.7, + "p25": 43.7, + "p75": 51.9, + "p90": 54.8, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 53.8, + "median": 55.5, + "p10": 44.8, + "p25": 48.4, + "p75": 59.0, + "p90": 61.8, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 47.9, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 54.3, + "p90": 57.1, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 5.2, + "median": 4.7, + "std": 2.1, + "min": 1.2, + "max": 16.5, + "p25": 3.9, + "p75": 5.9, + "p85": 5.9, + "p95": 7.8 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 3.5 + }, + { + "date": "2022-07-05", + "value": 5.9 + }, + { + "date": "2022-10-12", + "value": 2.4 + }, + { + "date": "2023-01-20", + "value": 8.3 + }, + { + "date": "2023-04-15", + "value": 4.7 + }, + { + "date": "2023-07-28", + "value": 7.1 + }, + { + "date": "2023-10-05", + "value": 3.5 + }, + { + "date": "2024-01-12", + "value": 16.5 + }, + { + "date": "2024-04-22", + "value": 4.7 + }, + { + "date": "2024-07-10", + "value": 9.4 + }, + { + "date": "2024-10-18", + "value": 3.5 + }, + { + "date": "2025-01-25", + "value": 5.9 + }, + { + "date": "2025-05-08", + "value": 1.2 + }, + { + "date": "2025-08-15", + "value": 7.1 + }, + { + "date": "2025-09-04", + "value": 3.5 + }, + { + "date": "2025-09-10", + "value": 4.7 + }, + { + "date": "2025-09-16", + "value": 4.7 + }, + { + "date": "2025-09-22", + "value": 4.7 + }, + { + "date": "2025-10-05", + "value": 3.5 + }, + { + "date": "2025-10-11", + "value": 4.7 + }, + { + "date": "2025-10-17", + "value": 4.7 + }, + { + "date": "2025-10-23", + "value": 4.7 + }, + { + "date": "2025-11-06", + "value": 4.7 + }, + { + "date": "2025-11-12", + "value": 5.9 + }, + { + "date": "2025-11-18", + "value": 5.9 + }, + { + "date": "2025-11-24", + "value": 5.9 + }, + { + "date": "2025-12-04", + "value": 4.7 + }, + { + "date": "2025-12-10", + "value": 5.9 + }, + { + "date": "2025-12-16", + "value": 5.9 + }, + { + "date": "2025-12-22", + "value": 3.5 + }, + { + "date": "2026-01-05", + "value": 4.7 + }, + { + "date": "2026-01-11", + "value": 5.9 + }, + { + "date": "2026-01-17", + "value": 3.5 + }, + { + "date": "2026-01-23", + "value": 3.5 + }, + { + "date": "2026-02-06", + "value": 5.9 + }, + { + "date": "2026-02-12", + "value": 3.5 + }, + { + "date": "2026-02-18", + "value": 4.7 + }, + { + "date": "2026-02-24", + "value": 4.7 + }, + { + "date": "2026-03-04", + "value": 3.5 + }, + { + "date": "2026-03-10", + "value": 3.5 + }, + { + "date": "2026-03-16", + "value": 4.7 + }, + { + "date": "2026-03-22", + "value": 4.7 + }, + { + "date": "2026-04-05", + "value": 4.7 + }, + { + "date": "2026-04-11", + "value": 4.7 + }, + { + "date": "2026-04-17", + "value": 5.9 + }, + { + "date": "2026-04-23", + "value": 5.9 + }, + { + "date": "2026-05-06", + "value": 4.7 + }, + { + "date": "2026-05-12", + "value": 4.7 + }, + { + "date": "2026-05-18", + "value": 5.9 + }, + { + "date": "2026-05-24", + "value": 5.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-01", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2023-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 16.5, + "median": 16.5, + "p10": 16.5, + "p25": 16.5, + "p75": 16.5, + "p90": 16.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2024-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-01", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 5.7, + "median": 5.9, + "p10": 5.1, + "p25": 5.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2025-12", + "mean": 5.1, + "median": 5.3, + "p10": 3.9, + "p25": 4.5, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.5, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 5.1, + "p90": 5.5, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.7, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 5.1, + "p90": 5.5, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 5.3, + "median": 5.3, + "p10": 4.7, + "p25": 4.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2026-05", + "mean": 5.3, + "median": 5.3, + "p10": 4.7, + "p25": 4.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 20.5, + "median": 18.9, + "std": 10.6, + "min": 2.4, + "max": 64.9, + "p25": 15.3, + "p75": 22.4, + "p85": 24.1, + "p95": 43.7 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 14.75, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 14.2 + }, + { + "date": "2022-05-15", + "value": 29.5 + }, + { + "date": "2022-05-22", + "value": 9.4 + }, + { + "date": "2022-11-03", + "value": 41.3 + }, + { + "date": "2022-11-10", + "value": 17.7 + }, + { + "date": "2022-11-18", + "value": 5.9 + }, + { + "date": "2022-11-25", + "value": 26.0 + }, + { + "date": "2023-05-08", + "value": 21.2 + }, + { + "date": "2023-05-15", + "value": 47.2 + }, + { + "date": "2023-05-22", + "value": 11.8 + }, + { + "date": "2023-11-06", + "value": 64.9 + }, + { + "date": "2023-11-13", + "value": 2.4 + }, + { + "date": "2023-11-20", + "value": 33.0 + }, + { + "date": "2023-11-27", + "value": 17.7 + }, + { + "date": "2023-11-30", + "value": 9.4 + }, + { + "date": "2024-05-06", + "value": 23.6 + }, + { + "date": "2024-05-13", + "value": 53.1 + }, + { + "date": "2024-05-20", + "value": 14.2 + }, + { + "date": "2024-05-27", + "value": 3.5 + }, + { + "date": "2024-11-04", + "value": 21.2 + }, + { + "date": "2024-11-11", + "value": 35.4 + }, + { + "date": "2024-11-18", + "value": 9.4 + }, + { + "date": "2025-05-05", + "value": 26.0 + }, + { + "date": "2025-05-09", + "value": 41.3 + }, + { + "date": "2025-05-13", + "value": 5.9 + }, + { + "date": "2025-05-17", + "value": 17.7 + }, + { + "date": "2025-05-21", + "value": 49.6 + }, + { + "date": "2025-05-25", + "value": 11.8 + }, + { + "date": "2025-09-05", + "value": 16.5 + }, + { + "date": "2025-09-11", + "value": 18.9 + }, + { + "date": "2025-09-17", + "value": 20.1 + }, + { + "date": "2025-09-23", + "value": 21.2 + }, + { + "date": "2025-09-29", + "value": 22.4 + }, + { + "date": "2025-10-06", + "value": 16.5 + }, + { + "date": "2025-10-12", + "value": 17.7 + }, + { + "date": "2025-10-18", + "value": 18.9 + }, + { + "date": "2025-10-24", + "value": 21.2 + }, + { + "date": "2025-10-30", + "value": 13.0 + }, + { + "date": "2025-11-04", + "value": 21.2 + }, + { + "date": "2025-11-10", + "value": 22.4 + }, + { + "date": "2025-11-16", + "value": 23.6 + }, + { + "date": "2025-11-22", + "value": 16.5 + }, + { + "date": "2025-11-28", + "value": 17.7 + }, + { + "date": "2025-12-05", + "value": 20.1 + }, + { + "date": "2025-12-11", + "value": 22.4 + }, + { + "date": "2025-12-17", + "value": 14.2 + }, + { + "date": "2025-12-23", + "value": 16.5 + }, + { + "date": "2025-12-29", + "value": 17.7 + }, + { + "date": "2026-01-06", + "value": 20.1 + }, + { + "date": "2026-01-12", + "value": 13.0 + }, + { + "date": "2026-01-18", + "value": 14.2 + }, + { + "date": "2026-01-24", + "value": 15.3 + }, + { + "date": "2026-01-30", + "value": 16.5 + }, + { + "date": "2026-02-04", + "value": 15.3 + }, + { + "date": "2026-02-10", + "value": 16.5 + }, + { + "date": "2026-02-16", + "value": 18.9 + }, + { + "date": "2026-02-22", + "value": 20.1 + }, + { + "date": "2026-02-28", + "value": 21.2 + }, + { + "date": "2026-03-05", + "value": 15.3 + }, + { + "date": "2026-03-11", + "value": 16.5 + }, + { + "date": "2026-03-17", + "value": 17.7 + }, + { + "date": "2026-03-23", + "value": 18.9 + }, + { + "date": "2026-03-29", + "value": 21.2 + }, + { + "date": "2026-04-06", + "value": 18.9 + }, + { + "date": "2026-04-12", + "value": 21.2 + }, + { + "date": "2026-04-18", + "value": 22.4 + }, + { + "date": "2026-04-24", + "value": 23.6 + }, + { + "date": "2026-04-30", + "value": 16.5 + }, + { + "date": "2026-05-04", + "value": 18.9 + }, + { + "date": "2026-05-10", + "value": 20.1 + }, + { + "date": "2026-05-16", + "value": 22.4 + }, + { + "date": "2026-05-22", + "value": 14.2 + }, + { + "date": "2026-05-28", + "value": 16.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 17.7, + "median": 14.2, + "p10": 10.4, + "p25": 11.8, + "p75": 21.8, + "p90": 26.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 22.8, + "median": 21.8, + "p10": 9.4, + "p25": 14.8, + "p75": 29.9, + "p90": 36.7, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 26.8, + "median": 21.2, + "p10": 13.7, + "p25": 16.5, + "p75": 34.2, + "p90": 42.0, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 25.5, + "median": 17.7, + "p10": 5.2, + "p25": 9.4, + "p75": 33.0, + "p90": 52.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 23.6, + "median": 18.9, + "p10": 6.7, + "p25": 11.6, + "p75": 31.0, + "p90": 44.2, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 22.1, + "median": 21.2, + "p10": 11.8, + "p25": 15.3, + "p75": 28.3, + "p90": 32.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 25.4, + "median": 21.8, + "p10": 8.8, + "p25": 13.3, + "p75": 37.5, + "p90": 45.4, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 19.8, + "median": 20.1, + "p10": 17.5, + "p25": 18.9, + "p75": 21.2, + "p90": 21.9, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 17.5, + "median": 17.7, + "p10": 14.4, + "p25": 16.5, + "p75": 18.9, + "p90": 20.3, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 20.3, + "median": 21.2, + "p10": 17.0, + "p25": 17.7, + "p75": 22.4, + "p90": 23.1, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 18.2, + "median": 17.7, + "p10": 15.1, + "p25": 16.5, + "p75": 20.1, + "p90": 21.5, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 15.8, + "median": 15.3, + "p10": 13.5, + "p25": 14.2, + "p75": 16.5, + "p90": 18.6, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 18.4, + "median": 18.9, + "p10": 15.8, + "p25": 16.5, + "p75": 20.1, + "p90": 20.8, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 17.9, + "median": 17.7, + "p10": 15.8, + "p25": 16.5, + "p75": 18.9, + "p90": 20.3, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 20.5, + "median": 21.2, + "p10": 17.5, + "p25": 18.9, + "p75": 22.4, + "p90": 23.1, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 18.4, + "median": 18.9, + "p10": 15.1, + "p25": 16.5, + "p75": 20.1, + "p90": 21.5, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 3.8, + "median": 3.5, + "std": 1.7, + "min": 0.0, + "max": 11.8, + "p25": 3.5, + "p75": 4.7, + "p85": 4.7, + "p95": 6.1 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 2.4 + }, + { + "date": "2022-06-10", + "value": 3.5 + }, + { + "date": "2022-07-15", + "value": 1.2 + }, + { + "date": "2022-08-22", + "value": 4.7 + }, + { + "date": "2022-10-05", + "value": 2.4 + }, + { + "date": "2022-11-18", + "value": 5.9 + }, + { + "date": "2023-01-10", + "value": 3.5 + }, + { + "date": "2023-03-25", + "value": 8.3 + }, + { + "date": "2023-05-12", + "value": 2.4 + }, + { + "date": "2023-07-08", + "value": 4.7 + }, + { + "date": "2023-09-15", + "value": 1.2 + }, + { + "date": "2023-11-22", + "value": 3.5 + }, + { + "date": "2024-01-18", + "value": 11.8 + }, + { + "date": "2024-03-08", + "value": 3.5 + }, + { + "date": "2024-05-15", + "value": 2.4 + }, + { + "date": "2024-07-22", + "value": 5.9 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 4.7 + }, + { + "date": "2025-01-15", + "value": 3.5 + }, + { + "date": "2025-03-20", + "value": 2.4 + }, + { + "date": "2025-05-28", + "value": 7.1 + }, + { + "date": "2025-08-05", + "value": 3.5 + }, + { + "date": "2025-09-05", + "value": 4.7 + }, + { + "date": "2025-09-11", + "value": 4.7 + }, + { + "date": "2025-09-17", + "value": 3.5 + }, + { + "date": "2025-09-23", + "value": 3.5 + }, + { + "date": "2025-10-06", + "value": 4.7 + }, + { + "date": "2025-10-12", + "value": 2.4 + }, + { + "date": "2025-10-18", + "value": 3.5 + }, + { + "date": "2025-10-24", + "value": 3.5 + }, + { + "date": "2025-11-04", + "value": 2.4 + }, + { + "date": "2025-11-10", + "value": 2.4 + }, + { + "date": "2025-11-16", + "value": 3.5 + }, + { + "date": "2025-11-22", + "value": 3.5 + }, + { + "date": "2025-12-05", + "value": 3.5 + }, + { + "date": "2025-12-11", + "value": 3.5 + }, + { + "date": "2025-12-17", + "value": 3.5 + }, + { + "date": "2025-12-23", + "value": 4.7 + }, + { + "date": "2026-01-06", + "value": 3.5 + }, + { + "date": "2026-01-12", + "value": 3.5 + }, + { + "date": "2026-01-18", + "value": 3.5 + }, + { + "date": "2026-01-24", + "value": 4.7 + }, + { + "date": "2026-02-04", + "value": 4.7 + }, + { + "date": "2026-02-10", + "value": 4.7 + }, + { + "date": "2026-02-16", + "value": 4.7 + }, + { + "date": "2026-02-22", + "value": 3.5 + }, + { + "date": "2026-03-05", + "value": 3.5 + }, + { + "date": "2026-03-11", + "value": 4.7 + }, + { + "date": "2026-03-17", + "value": 2.4 + }, + { + "date": "2026-03-23", + "value": 3.5 + }, + { + "date": "2026-04-06", + "value": 3.5 + }, + { + "date": "2026-04-12", + "value": 2.4 + }, + { + "date": "2026-04-18", + "value": 2.4 + }, + { + "date": "2026-04-24", + "value": 3.5 + }, + { + "date": "2026-05-04", + "value": 3.5 + }, + { + "date": "2026-05-10", + "value": 3.5 + }, + { + "date": "2026-05-16", + "value": 3.5 + }, + { + "date": "2026-05-22", + "value": 3.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-06", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2022-08", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-11", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1 + }, + { + "month": "2024-03", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2025-05", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.9, + "median": 2.9, + "p10": 2.4, + "p25": 2.4, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.9, + "median": 2.9, + "p10": 2.4, + "p25": 2.4, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 4.0, + "median": 3.5, + "std": 2.1, + "min": 0.0, + "max": 15.3, + "p25": 3.5, + "p75": 4.7, + "p85": 4.7, + "p95": 7.3 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 2.4 + }, + { + "date": "2022-06-13", + "value": 1.2 + }, + { + "date": "2022-07-16", + "value": 3.5 + }, + { + "date": "2022-08-26", + "value": 2.4 + }, + { + "date": "2022-10-07", + "value": 5.9 + }, + { + "date": "2022-11-23", + "value": 2.4 + }, + { + "date": "2023-01-13", + "value": 4.7 + }, + { + "date": "2023-04-01", + "value": 3.5 + }, + { + "date": "2023-05-14", + "value": 7.1 + }, + { + "date": "2023-07-12", + "value": 2.4 + }, + { + "date": "2023-09-16", + "value": 15.3 + }, + { + "date": "2023-11-25", + "value": 3.5 + }, + { + "date": "2024-01-28", + "value": 8.3 + }, + { + "date": "2024-03-11", + "value": 1.2 + }, + { + "date": "2024-05-17", + "value": 4.7 + }, + { + "date": "2024-07-27", + "value": 5.9 + }, + { + "date": "2024-09-10", + "value": 2.4 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 3.5 + }, + { + "date": "2025-03-22", + "value": 9.4 + }, + { + "date": "2025-06-03", + "value": 2.4 + }, + { + "date": "2025-08-08", + "value": 5.9 + }, + { + "date": "2025-09-04", + "value": 2.4 + }, + { + "date": "2025-09-10", + "value": 3.5 + }, + { + "date": "2025-09-16", + "value": 3.5 + }, + { + "date": "2025-09-22", + "value": 3.5 + }, + { + "date": "2025-10-05", + "value": 3.5 + }, + { + "date": "2025-10-11", + "value": 3.5 + }, + { + "date": "2025-10-17", + "value": 4.7 + }, + { + "date": "2025-10-23", + "value": 4.7 + }, + { + "date": "2025-11-06", + "value": 3.5 + }, + { + "date": "2025-11-12", + "value": 3.5 + }, + { + "date": "2025-11-18", + "value": 3.5 + }, + { + "date": "2025-11-24", + "value": 4.7 + }, + { + "date": "2025-12-04", + "value": 3.5 + }, + { + "date": "2025-12-10", + "value": 3.5 + }, + { + "date": "2025-12-16", + "value": 3.5 + }, + { + "date": "2025-12-22", + "value": 2.4 + }, + { + "date": "2026-01-05", + "value": 4.7 + }, + { + "date": "2026-01-11", + "value": 4.7 + }, + { + "date": "2026-01-17", + "value": 3.5 + }, + { + "date": "2026-01-23", + "value": 3.5 + }, + { + "date": "2026-02-06", + "value": 4.7 + }, + { + "date": "2026-02-12", + "value": 2.4 + }, + { + "date": "2026-02-18", + "value": 3.5 + }, + { + "date": "2026-02-24", + "value": 3.5 + }, + { + "date": "2026-03-04", + "value": 3.5 + }, + { + "date": "2026-03-10", + "value": 3.5 + }, + { + "date": "2026-03-16", + "value": 3.5 + }, + { + "date": "2026-03-22", + "value": 4.7 + }, + { + "date": "2026-04-05", + "value": 3.5 + }, + { + "date": "2026-04-11", + "value": 3.5 + }, + { + "date": "2026-04-17", + "value": 3.5 + }, + { + "date": "2026-04-23", + "value": 3.5 + }, + { + "date": "2026-05-06", + "value": 3.5 + }, + { + "date": "2026-05-12", + "value": 3.5 + }, + { + "date": "2026-05-18", + "value": 3.5 + }, + { + "date": "2026-05-24", + "value": 3.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-10", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-09", + "mean": 15.3, + "median": 15.3, + "p10": 15.3, + "p25": 15.3, + "p75": 15.3, + "p90": 15.3, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.3, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.3, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 15.0, + "median": 14.2, + "std": 6.6, + "min": 2.4, + "max": 49.6, + "p25": 11.8, + "p75": 16.5, + "p85": 17.7, + "p95": 24.1 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 33.63, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 9.4 + }, + { + "date": "2023-03-25", + "value": 26.0 + }, + { + "date": "2023-09-20", + "value": 49.6 + }, + { + "date": "2024-03-15", + "value": 7.1 + }, + { + "date": "2024-03-28", + "value": 21.2 + }, + { + "date": "2024-09-05", + "value": 33.0 + }, + { + "date": "2024-09-15", + "value": 14.2 + }, + { + "date": "2024-09-25", + "value": 2.4 + }, + { + "date": "2025-03-10", + "value": 17.7 + }, + { + "date": "2025-03-22", + "value": 5.9 + }, + { + "date": "2025-07-08", + "value": 23.6 + }, + { + "date": "2025-07-22", + "value": 4.7 + }, + { + "date": "2025-09-05", + "value": 16.5 + }, + { + "date": "2025-09-11", + "value": 17.7 + }, + { + "date": "2025-09-17", + "value": 11.8 + }, + { + "date": "2025-09-23", + "value": 13.0 + }, + { + "date": "2025-09-29", + "value": 14.2 + }, + { + "date": "2025-10-06", + "value": 16.5 + }, + { + "date": "2025-10-12", + "value": 9.4 + }, + { + "date": "2025-10-18", + "value": 11.8 + }, + { + "date": "2025-10-24", + "value": 13.0 + }, + { + "date": "2025-10-30", + "value": 13.0 + }, + { + "date": "2025-11-04", + "value": 11.8 + }, + { + "date": "2025-11-10", + "value": 14.2 + }, + { + "date": "2025-11-16", + "value": 14.2 + }, + { + "date": "2025-11-22", + "value": 15.3 + }, + { + "date": "2025-11-28", + "value": 16.5 + }, + { + "date": "2025-12-05", + "value": 11.8 + }, + { + "date": "2025-12-11", + "value": 13.0 + }, + { + "date": "2025-12-17", + "value": 14.2 + }, + { + "date": "2025-12-23", + "value": 15.3 + }, + { + "date": "2025-12-29", + "value": 16.5 + }, + { + "date": "2026-01-06", + "value": 15.3 + }, + { + "date": "2026-01-12", + "value": 16.5 + }, + { + "date": "2026-01-18", + "value": 17.7 + }, + { + "date": "2026-01-24", + "value": 18.9 + }, + { + "date": "2026-01-30", + "value": 13.0 + }, + { + "date": "2026-02-04", + "value": 15.3 + }, + { + "date": "2026-02-10", + "value": 16.5 + }, + { + "date": "2026-02-16", + "value": 17.7 + }, + { + "date": "2026-02-22", + "value": 11.8 + }, + { + "date": "2026-02-28", + "value": 13.0 + }, + { + "date": "2026-03-05", + "value": 15.3 + }, + { + "date": "2026-03-11", + "value": 16.5 + }, + { + "date": "2026-03-17", + "value": 9.4 + }, + { + "date": "2026-03-23", + "value": 11.8 + }, + { + "date": "2026-03-29", + "value": 13.0 + }, + { + "date": "2026-04-06", + "value": 18.9 + }, + { + "date": "2026-04-12", + "value": 11.8 + }, + { + "date": "2026-04-18", + "value": 14.2 + }, + { + "date": "2026-04-24", + "value": 14.2 + }, + { + "date": "2026-04-30", + "value": 15.3 + }, + { + "date": "2026-05-04", + "value": 10.6 + }, + { + "date": "2026-05-10", + "value": 11.8 + }, + { + "date": "2026-05-16", + "value": 13.0 + }, + { + "date": "2026-05-22", + "value": 14.2 + }, + { + "date": "2026-05-28", + "value": 15.3 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 17.7, + "median": 17.7, + "p10": 11.1, + "p25": 13.6, + "p75": 21.8, + "p90": 24.3, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 14.2, + "median": 14.2, + "p10": 8.5, + "p25": 10.6, + "p75": 17.7, + "p90": 19.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 16.5, + "median": 14.2, + "p10": 4.7, + "p25": 8.3, + "p75": 23.6, + "p90": 29.3, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 11.8, + "median": 11.8, + "p10": 7.1, + "p25": 8.8, + "p75": 14.8, + "p90": 16.5, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 14.2, + "median": 14.2, + "p10": 6.6, + "p25": 9.4, + "p75": 18.9, + "p90": 21.7, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 14.6, + "median": 14.2, + "p10": 12.3, + "p25": 13.0, + "p75": 16.5, + "p90": 17.2, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 12.7, + "median": 13.0, + "p10": 10.4, + "p25": 11.8, + "p75": 13.0, + "p90": 15.1, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 14.4, + "median": 14.2, + "p10": 12.7, + "p25": 14.2, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 14.2, + "median": 14.2, + "p10": 12.3, + "p25": 13.0, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 16.3, + "median": 16.5, + "p10": 13.9, + "p25": 15.3, + "p75": 17.7, + "p90": 18.4, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 14.9, + "median": 15.3, + "p10": 12.3, + "p25": 13.0, + "p75": 16.5, + "p90": 17.2, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 13.2, + "median": 13.0, + "p10": 10.4, + "p25": 11.8, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 14.9, + "median": 14.2, + "p10": 12.7, + "p25": 14.2, + "p75": 15.3, + "p90": 17.5, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 13.0, + "median": 13.0, + "p10": 11.1, + "p25": 11.8, + "p75": 14.2, + "p90": 14.9, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 24.7, + "median": 24.8, + "std": 5.4, + "min": 14.2, + "max": 44.8, + "p25": 21.8, + "p75": 27.1, + "p85": 29.4, + "p95": 31.4 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 21.2 + }, + { + "date": "2023-10-12", + "value": 29.5 + }, + { + "date": "2024-04-08", + "value": 14.2 + }, + { + "date": "2024-09-20", + "value": 44.8 + }, + { + "date": "2024-10-15", + "value": 23.6 + }, + { + "date": "2025-03-25", + "value": 17.7 + }, + { + "date": "2025-04-10", + "value": 33.0 + }, + { + "date": "2025-07-30", + "value": 28.3 + }, + { + "date": "2025-09-04", + "value": 20.1 + }, + { + "date": "2025-09-10", + "value": 22.4 + }, + { + "date": "2025-09-16", + "value": 24.8 + }, + { + "date": "2025-10-05", + "value": 20.1 + }, + { + "date": "2025-10-11", + "value": 22.4 + }, + { + "date": "2025-10-17", + "value": 23.6 + }, + { + "date": "2025-11-06", + "value": 26.0 + }, + { + "date": "2025-11-12", + "value": 27.1 + }, + { + "date": "2025-11-18", + "value": 29.5 + }, + { + "date": "2025-12-04", + "value": 24.8 + }, + { + "date": "2025-12-10", + "value": 27.1 + }, + { + "date": "2025-12-16", + "value": 29.5 + }, + { + "date": "2026-01-05", + "value": 24.8 + }, + { + "date": "2026-01-11", + "value": 27.1 + }, + { + "date": "2026-01-17", + "value": 16.5 + }, + { + "date": "2026-02-06", + "value": 30.7 + }, + { + "date": "2026-02-12", + "value": 20.1 + }, + { + "date": "2026-02-18", + "value": 22.4 + }, + { + "date": "2026-03-04", + "value": 17.7 + }, + { + "date": "2026-03-10", + "value": 20.1 + }, + { + "date": "2026-03-16", + "value": 22.4 + }, + { + "date": "2026-04-05", + "value": 23.6 + }, + { + "date": "2026-04-11", + "value": 26.0 + }, + { + "date": "2026-04-17", + "value": 27.1 + }, + { + "date": "2026-05-06", + "value": 23.6 + }, + { + "date": "2026-05-12", + "value": 24.8 + }, + { + "date": "2026-05-18", + "value": 27.1 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2023-10", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2024-09", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 23.6, + "median": 23.6, + "p10": 23.6, + "p25": 23.6, + "p75": 23.6, + "p90": 23.6, + "n": 1 + }, + { + "month": "2025-03", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2025-04", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 28.3, + "median": 28.3, + "p10": 28.3, + "p25": 28.3, + "p75": 28.3, + "p90": 28.3, + "n": 1 + }, + { + "month": "2025-09", + "mean": 22.4, + "median": 22.4, + "p10": 20.5, + "p25": 21.2, + "p75": 23.6, + "p90": 24.3, + "n": 3 + }, + { + "month": "2025-10", + "mean": 22.1, + "median": 22.4, + "p10": 20.5, + "p25": 21.2, + "p75": 23.0, + "p90": 23.4, + "n": 3 + }, + { + "month": "2025-11", + "mean": 27.5, + "median": 27.1, + "p10": 26.2, + "p25": 26.5, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2025-12", + "mean": 27.1, + "median": 27.1, + "p10": 25.3, + "p25": 26.0, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-01", + "mean": 22.8, + "median": 24.8, + "p10": 18.2, + "p25": 20.6, + "p75": 26.0, + "p90": 26.7, + "n": 3 + }, + { + "month": "2026-02", + "mean": 24.4, + "median": 22.4, + "p10": 20.5, + "p25": 21.2, + "p75": 26.5, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-03", + "mean": 20.1, + "median": 20.1, + "p10": 18.2, + "p25": 18.9, + "p75": 21.2, + "p90": 21.9, + "n": 3 + }, + { + "month": "2026-04", + "mean": 25.6, + "median": 26.0, + "p10": 24.1, + "p25": 24.8, + "p75": 26.5, + "p90": 26.9, + "n": 3 + }, + { + "month": "2026-05", + "mean": 25.1, + "median": 24.8, + "p10": 23.8, + "p25": 24.2, + "p75": 26.0, + "p90": 26.7, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 36.9, + "median": 36.0, + "std": 8.4, + "min": 17.7, + "max": 64.9, + "p25": 31.9, + "p75": 42.5, + "p85": 44.8, + "p95": 49.4 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 33.0 + }, + { + "date": "2022-11-30", + "value": 41.3 + }, + { + "date": "2023-03-15", + "value": 26.0 + }, + { + "date": "2023-07-10", + "value": 49.6 + }, + { + "date": "2023-10-25", + "value": 35.4 + }, + { + "date": "2024-02-08", + "value": 64.9 + }, + { + "date": "2024-05-20", + "value": 29.5 + }, + { + "date": "2024-08-12", + "value": 44.8 + }, + { + "date": "2024-11-05", + "value": 17.7 + }, + { + "date": "2025-01-22", + "value": 37.8 + }, + { + "date": "2025-04-10", + "value": 33.0 + }, + { + "date": "2025-06-18", + "value": 53.1 + }, + { + "date": "2025-07-15", + "value": 35.4 + }, + { + "date": "2025-08-05", + "value": 26.0 + }, + { + "date": "2025-09-05", + "value": 42.5 + }, + { + "date": "2025-09-10", + "value": 44.8 + }, + { + "date": "2025-09-11", + "value": 46.0 + }, + { + "date": "2025-09-17", + "value": 30.7 + }, + { + "date": "2025-10-06", + "value": 42.5 + }, + { + "date": "2025-10-12", + "value": 27.1 + }, + { + "date": "2025-10-18", + "value": 30.7 + }, + { + "date": "2025-11-04", + "value": 31.9 + }, + { + "date": "2025-11-10", + "value": 36.6 + }, + { + "date": "2025-11-16", + "value": 38.9 + }, + { + "date": "2025-12-05", + "value": 31.9 + }, + { + "date": "2025-12-11", + "value": 34.2 + }, + { + "date": "2025-12-17", + "value": 37.8 + }, + { + "date": "2026-01-06", + "value": 30.7 + }, + { + "date": "2026-01-12", + "value": 34.2 + }, + { + "date": "2026-01-18", + "value": 36.6 + }, + { + "date": "2026-02-04", + "value": 38.9 + }, + { + "date": "2026-02-10", + "value": 42.5 + }, + { + "date": "2026-02-16", + "value": 46.0 + }, + { + "date": "2026-03-05", + "value": 38.9 + }, + { + "date": "2026-03-11", + "value": 42.5 + }, + { + "date": "2026-03-17", + "value": 27.1 + }, + { + "date": "2026-04-06", + "value": 47.2 + }, + { + "date": "2026-04-12", + "value": 31.9 + }, + { + "date": "2026-04-18", + "value": 36.6 + }, + { + "date": "2026-05-04", + "value": 28.3 + }, + { + "date": "2026-05-10", + "value": 31.9 + }, + { + "date": "2026-05-16", + "value": 34.2 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2023-03", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1 + }, + { + "month": "2023-10", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2024-02", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2024-05", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-11", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-04", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 53.1, + "median": 53.1, + "p10": 53.1, + "p25": 53.1, + "p75": 53.1, + "p90": 53.1, + "n": 1 + }, + { + "month": "2025-07", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 41.1, + "median": 43.7, + "p10": 34.2, + "p25": 39.5, + "p75": 45.2, + "p90": 45.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 33.4, + "median": 30.7, + "p10": 27.8, + "p25": 28.9, + "p75": 36.6, + "p90": 40.1, + "n": 3 + }, + { + "month": "2025-11", + "mean": 35.8, + "median": 36.6, + "p10": 32.8, + "p25": 34.2, + "p75": 37.8, + "p90": 38.5, + "n": 3 + }, + { + "month": "2025-12", + "mean": 34.6, + "median": 34.2, + "p10": 32.3, + "p25": 33.0, + "p75": 36.0, + "p90": 37.1, + "n": 3 + }, + { + "month": "2026-01", + "mean": 33.9, + "median": 34.2, + "p10": 31.4, + "p25": 32.4, + "p75": 35.4, + "p90": 36.1, + "n": 3 + }, + { + "month": "2026-02", + "mean": 42.5, + "median": 42.5, + "p10": 39.6, + "p25": 40.7, + "p75": 44.2, + "p90": 45.3, + "n": 3 + }, + { + "month": "2026-03", + "mean": 36.2, + "median": 38.9, + "p10": 29.5, + "p25": 33.0, + "p75": 40.7, + "p90": 41.8, + "n": 3 + }, + { + "month": "2026-04", + "mean": 38.6, + "median": 36.6, + "p10": 32.8, + "p25": 34.2, + "p75": 41.9, + "p90": 45.1, + "n": 3 + }, + { + "month": "2026-05", + "mean": 31.5, + "median": 31.9, + "p10": 29.0, + "p25": 30.1, + "p75": 33.0, + "p90": 33.7, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 53.1, + "median": 51.9, + "std": 16.5, + "min": 11.8, + "max": 112.1, + "p25": 42.5, + "p75": 57.8, + "p85": 62.5, + "p95": 79.8 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 33.63, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 49.6 + }, + { + "date": "2023-05-05", + "value": 76.7 + }, + { + "date": "2023-05-20", + "value": 33.0 + }, + { + "date": "2024-01-10", + "value": 112.1 + }, + { + "date": "2024-01-25", + "value": 41.3 + }, + { + "date": "2024-08-15", + "value": 11.8 + }, + { + "date": "2025-02-05", + "value": 92.0 + }, + { + "date": "2025-02-18", + "value": 64.9 + }, + { + "date": "2025-08-10", + "value": 49.6 + }, + { + "date": "2025-08-20", + "value": 37.8 + }, + { + "date": "2025-09-06", + "value": 46.0 + }, + { + "date": "2025-09-12", + "value": 49.6 + }, + { + "date": "2025-09-18", + "value": 54.3 + }, + { + "date": "2025-10-04", + "value": 57.8 + }, + { + "date": "2025-10-10", + "value": 62.5 + }, + { + "date": "2025-10-16", + "value": 67.3 + }, + { + "date": "2025-11-05", + "value": 56.6 + }, + { + "date": "2025-11-11", + "value": 61.4 + }, + { + "date": "2025-11-17", + "value": 40.1 + }, + { + "date": "2025-12-06", + "value": 56.6 + }, + { + "date": "2025-12-12", + "value": 35.4 + }, + { + "date": "2025-12-18", + "value": 40.1 + }, + { + "date": "2026-01-04", + "value": 42.5 + }, + { + "date": "2026-01-10", + "value": 48.4 + }, + { + "date": "2026-01-16", + "value": 50.7 + }, + { + "date": "2026-02-05", + "value": 42.5 + }, + { + "date": "2026-02-11", + "value": 46.0 + }, + { + "date": "2026-02-17", + "value": 49.6 + }, + { + "date": "2026-03-06", + "value": 54.3 + }, + { + "date": "2026-03-12", + "value": 57.8 + }, + { + "date": "2026-03-18", + "value": 62.5 + }, + { + "date": "2026-04-04", + "value": 53.1 + }, + { + "date": "2026-04-10", + "value": 56.6 + }, + { + "date": "2026-04-16", + "value": 61.4 + }, + { + "date": "2026-05-05", + "value": 51.9 + }, + { + "date": "2026-05-11", + "value": 56.6 + }, + { + "date": "2026-05-17", + "value": 35.4 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 54.9, + "median": 54.9, + "p10": 37.4, + "p25": 44.0, + "p75": 65.8, + "p90": 72.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 76.7, + "median": 76.7, + "p10": 48.4, + "p25": 59.0, + "p75": 94.4, + "p90": 105.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 78.5, + "median": 78.5, + "p10": 67.6, + "p25": 71.7, + "p75": 85.3, + "p90": 89.3, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 43.7, + "median": 43.7, + "p10": 38.9, + "p25": 40.7, + "p75": 46.6, + "p90": 48.4, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 49.9, + "median": 49.6, + "p10": 46.7, + "p25": 47.8, + "p75": 51.9, + "p90": 53.3, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 62.5, + "median": 62.5, + "p10": 58.8, + "p25": 60.2, + "p75": 64.9, + "p90": 66.3, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 52.7, + "median": 56.6, + "p10": 43.4, + "p25": 48.4, + "p75": 59.0, + "p90": 60.4, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 44.0, + "median": 40.1, + "p10": 36.3, + "p25": 37.8, + "p75": 48.4, + "p90": 53.3, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 47.2, + "median": 48.4, + "p10": 43.7, + "p25": 45.4, + "p75": 49.6, + "p90": 50.3, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 46.0, + "median": 46.0, + "p10": 43.2, + "p25": 44.2, + "p75": 47.8, + "p90": 48.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 58.2, + "median": 57.8, + "p10": 55.0, + "p25": 56.0, + "p75": 60.2, + "p90": 61.6, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 57.0, + "median": 56.6, + "p10": 53.8, + "p25": 54.9, + "p75": 59.0, + "p90": 60.4, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 48.0, + "median": 51.9, + "p10": 38.7, + "p25": 43.7, + "p75": 54.3, + "p90": 55.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ] + }, + { + "id": "riverside-decaf", + "name": "Riverside Decaf", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 33.0, + "median": 32.8, + "std": 10.9, + "min": 6.6, + "max": 86.1, + "p25": 28.7, + "p75": 36.9, + "p85": 39.4, + "p95": 45.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 45.1 + }, + { + "date": "2022-06-10", + "value": 34.4 + }, + { + "date": "2022-09-22", + "value": 6.6 + }, + { + "date": "2022-12-05", + "value": 51.7 + }, + { + "date": "2023-02-14", + "value": 31.2 + }, + { + "date": "2023-05-30", + "value": 18.0 + }, + { + "date": "2023-08-17", + "value": 58.2 + }, + { + "date": "2023-11-02", + "value": 24.6 + }, + { + "date": "2024-01-25", + "value": 36.9 + }, + { + "date": "2024-04-11", + "value": 14.8 + }, + { + "date": "2024-07-09", + "value": 86.1 + }, + { + "date": "2024-10-03", + "value": 28.7 + }, + { + "date": "2025-01-20", + "value": 9.8 + }, + { + "date": "2025-04-08", + "value": 39.4 + }, + { + "date": "2025-09-05", + "value": 32.0 + }, + { + "date": "2025-09-11", + "value": 33.6 + }, + { + "date": "2025-09-17", + "value": 36.1 + }, + { + "date": "2025-09-23", + "value": 39.4 + }, + { + "date": "2025-09-29", + "value": 41.8 + }, + { + "date": "2025-10-06", + "value": 30.3 + }, + { + "date": "2025-10-12", + "value": 32.8 + }, + { + "date": "2025-10-18", + "value": 36.1 + }, + { + "date": "2025-10-24", + "value": 38.5 + }, + { + "date": "2025-10-30", + "value": 25.4 + }, + { + "date": "2025-11-04", + "value": 29.5 + }, + { + "date": "2025-11-10", + "value": 32.8 + }, + { + "date": "2025-11-16", + "value": 35.3 + }, + { + "date": "2025-11-22", + "value": 22.1 + }, + { + "date": "2025-11-28", + "value": 25.4 + }, + { + "date": "2025-12-05", + "value": 37.7 + }, + { + "date": "2025-12-11", + "value": 40.2 + }, + { + "date": "2025-12-17", + "value": 27.1 + }, + { + "date": "2025-12-23", + "value": 30.3 + }, + { + "date": "2025-12-29", + "value": 32.0 + }, + { + "date": "2026-01-06", + "value": 36.9 + }, + { + "date": "2026-01-12", + "value": 23.8 + }, + { + "date": "2026-01-18", + "value": 27.1 + }, + { + "date": "2026-01-24", + "value": 28.7 + }, + { + "date": "2026-01-30", + "value": 31.2 + }, + { + "date": "2026-02-04", + "value": 28.7 + }, + { + "date": "2026-02-10", + "value": 32.0 + }, + { + "date": "2026-02-16", + "value": 33.6 + }, + { + "date": "2026-02-22", + "value": 36.1 + }, + { + "date": "2026-02-28", + "value": 39.4 + }, + { + "date": "2026-03-05", + "value": 28.7 + }, + { + "date": "2026-03-11", + "value": 30.3 + }, + { + "date": "2026-03-17", + "value": 32.8 + }, + { + "date": "2026-03-23", + "value": 36.1 + }, + { + "date": "2026-03-29", + "value": 38.5 + }, + { + "date": "2026-04-06", + "value": 27.1 + }, + { + "date": "2026-04-12", + "value": 29.5 + }, + { + "date": "2026-04-18", + "value": 32.8 + }, + { + "date": "2026-04-24", + "value": 35.3 + }, + { + "date": "2026-04-30", + "value": 22.1 + }, + { + "date": "2026-05-04", + "value": 34.4 + }, + { + "date": "2026-05-10", + "value": 37.7 + }, + { + "date": "2026-05-16", + "value": 40.2 + }, + { + "date": "2026-05-22", + "value": 27.1 + }, + { + "date": "2026-05-28", + "value": 30.3 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2022-06", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1 + }, + { + "month": "2022-09", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2022-12", + "mean": 51.7, + "median": 51.7, + "p10": 51.7, + "p25": 51.7, + "p75": 51.7, + "p90": 51.7, + "n": 1 + }, + { + "month": "2023-02", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2023-05", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 58.2, + "median": 58.2, + "p10": 58.2, + "p25": 58.2, + "p75": 58.2, + "p90": 58.2, + "n": 1 + }, + { + "month": "2023-11", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2024-01", + "mean": 36.9, + "median": 36.9, + "p10": 36.9, + "p25": 36.9, + "p75": 36.9, + "p90": 36.9, + "n": 1 + }, + { + "month": "2024-04", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2024-07", + "mean": 86.1, + "median": 86.1, + "p10": 86.1, + "p25": 86.1, + "p75": 86.1, + "p90": 86.1, + "n": 1 + }, + { + "month": "2024-10", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2025-04", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2025-09", + "mean": 36.6, + "median": 36.1, + "p10": 32.6, + "p25": 33.6, + "p75": 39.4, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 32.6, + "median": 32.8, + "p10": 27.4, + "p25": 30.3, + "p75": 36.1, + "p90": 37.6, + "n": 5 + }, + { + "month": "2025-11", + "mean": 29.0, + "median": 29.5, + "p10": 23.5, + "p25": 25.4, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2025-12", + "mean": 33.5, + "median": 32.0, + "p10": 28.4, + "p25": 30.3, + "p75": 37.7, + "p90": 39.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 29.5, + "median": 28.7, + "p10": 25.1, + "p25": 27.1, + "p75": 31.2, + "p90": 34.6, + "n": 5 + }, + { + "month": "2026-02", + "mean": 33.9, + "median": 33.6, + "p10": 30.0, + "p25": 32.0, + "p75": 36.1, + "p90": 38.0, + "n": 5 + }, + { + "month": "2026-03", + "mean": 33.3, + "median": 32.8, + "p10": 29.4, + "p25": 30.3, + "p75": 36.1, + "p90": 37.6, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.4, + "median": 29.5, + "p10": 24.1, + "p25": 27.1, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 33.9, + "median": 34.4, + "p10": 28.4, + "p25": 30.3, + "p75": 37.7, + "p90": 39.2, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 27.4, + "median": 27.1, + "std": 9.3, + "min": 4.1, + "max": 67.2, + "p25": 23.0, + "p75": 31.2, + "p85": 33.4, + "p95": 42.3 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 26.2 + }, + { + "date": "2022-04-19", + "value": 39.4 + }, + { + "date": "2022-07-11", + "value": 4.1 + }, + { + "date": "2022-09-28", + "value": 54.9 + }, + { + "date": "2022-12-15", + "value": 20.5 + }, + { + "date": "2023-03-07", + "value": 33.6 + }, + { + "date": "2023-05-22", + "value": 12.3 + }, + { + "date": "2023-08-09", + "value": 67.2 + }, + { + "date": "2023-10-30", + "value": 31.2 + }, + { + "date": "2024-01-16", + "value": 16.4 + }, + { + "date": "2024-03-25", + "value": 42.6 + }, + { + "date": "2024-06-12", + "value": 8.2 + }, + { + "date": "2024-08-28", + "value": 36.1 + }, + { + "date": "2024-11-14", + "value": 23.0 + }, + { + "date": "2025-01-06", + "value": 28.7 + }, + { + "date": "2025-03-18", + "value": 14.8 + }, + { + "date": "2025-05-29", + "value": 45.1 + }, + { + "date": "2025-08-12", + "value": 21.3 + }, + { + "date": "2025-09-04", + "value": 21.3 + }, + { + "date": "2025-09-10", + "value": 23.8 + }, + { + "date": "2025-09-16", + "value": 25.4 + }, + { + "date": "2025-09-22", + "value": 27.9 + }, + { + "date": "2025-09-28", + "value": 30.3 + }, + { + "date": "2025-10-05", + "value": 21.3 + }, + { + "date": "2025-10-11", + "value": 23.0 + }, + { + "date": "2025-10-17", + "value": 25.4 + }, + { + "date": "2025-10-23", + "value": 27.1 + }, + { + "date": "2025-10-29", + "value": 29.5 + }, + { + "date": "2025-11-06", + "value": 27.1 + }, + { + "date": "2025-11-12", + "value": 29.5 + }, + { + "date": "2025-11-18", + "value": 31.2 + }, + { + "date": "2025-11-24", + "value": 34.4 + }, + { + "date": "2025-11-30", + "value": 23.0 + }, + { + "date": "2025-12-04", + "value": 26.2 + }, + { + "date": "2025-12-10", + "value": 28.7 + }, + { + "date": "2025-12-16", + "value": 31.2 + }, + { + "date": "2025-12-22", + "value": 19.7 + }, + { + "date": "2025-12-28", + "value": 23.0 + }, + { + "date": "2026-01-05", + "value": 32.8 + }, + { + "date": "2026-01-11", + "value": 35.3 + }, + { + "date": "2026-01-17", + "value": 23.8 + }, + { + "date": "2026-01-23", + "value": 27.1 + }, + { + "date": "2026-01-29", + "value": 28.7 + }, + { + "date": "2026-02-06", + "value": 32.8 + }, + { + "date": "2026-02-12", + "value": 21.3 + }, + { + "date": "2026-02-18", + "value": 23.8 + }, + { + "date": "2026-02-24", + "value": 25.4 + }, + { + "date": "2026-02-30", + "value": 27.9 + }, + { + "date": "2026-03-04", + "value": 18.0 + }, + { + "date": "2026-03-10", + "value": 21.3 + }, + { + "date": "2026-03-16", + "value": 23.0 + }, + { + "date": "2026-03-22", + "value": 25.4 + }, + { + "date": "2026-03-28", + "value": 27.1 + }, + { + "date": "2026-04-05", + "value": 25.4 + }, + { + "date": "2026-04-11", + "value": 27.1 + }, + { + "date": "2026-04-17", + "value": 29.5 + }, + { + "date": "2026-04-23", + "value": 31.2 + }, + { + "date": "2026-04-29", + "value": 34.4 + }, + { + "date": "2026-05-06", + "value": 24.6 + }, + { + "date": "2026-05-12", + "value": 26.2 + }, + { + "date": "2026-05-18", + "value": 28.7 + }, + { + "date": "2026-05-24", + "value": 31.2 + }, + { + "date": "2026-05-30", + "value": 19.7 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 26.2, + "median": 26.2, + "p10": 26.2, + "p25": 26.2, + "p75": 26.2, + "p90": 26.2, + "n": 1 + }, + { + "month": "2022-04", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-09", + "mean": 54.9, + "median": 54.9, + "p10": 54.9, + "p25": 54.9, + "p75": 54.9, + "p90": 54.9, + "n": 1 + }, + { + "month": "2022-12", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 33.6, + "median": 33.6, + "p10": 33.6, + "p25": 33.6, + "p75": 33.6, + "p90": 33.6, + "n": 1 + }, + { + "month": "2023-05", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2023-08", + "mean": 67.2, + "median": 67.2, + "p10": 67.2, + "p25": 67.2, + "p75": 67.2, + "p90": 67.2, + "n": 1 + }, + { + "month": "2023-10", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-01", + "mean": 16.4, + "median": 16.4, + "p10": 16.4, + "p25": 16.4, + "p75": 16.4, + "p90": 16.4, + "n": 1 + }, + { + "month": "2024-03", + "mean": 42.6, + "median": 42.6, + "p10": 42.6, + "p25": 42.6, + "p75": 42.6, + "p90": 42.6, + "n": 1 + }, + { + "month": "2024-06", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1 + }, + { + "month": "2024-08", + "mean": 36.1, + "median": 36.1, + "p10": 36.1, + "p25": 36.1, + "p75": 36.1, + "p90": 36.1, + "n": 1 + }, + { + "month": "2024-11", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2025-03", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2025-05", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 21.3, + "median": 21.3, + "p10": 21.3, + "p25": 21.3, + "p75": 21.3, + "p90": 21.3, + "n": 1 + }, + { + "month": "2025-09", + "mean": 25.7, + "median": 25.4, + "p10": 22.3, + "p25": 23.8, + "p75": 27.9, + "p90": 29.4, + "n": 5 + }, + { + "month": "2025-10", + "mean": 25.3, + "median": 25.4, + "p10": 22.0, + "p25": 23.0, + "p75": 27.1, + "p90": 28.5, + "n": 5 + }, + { + "month": "2025-11", + "mean": 29.0, + "median": 29.5, + "p10": 24.6, + "p25": 27.1, + "p75": 31.2, + "p90": 33.1, + "n": 5 + }, + { + "month": "2025-12", + "mean": 25.7, + "median": 26.2, + "p10": 21.0, + "p25": 23.0, + "p75": 28.7, + "p90": 30.2, + "n": 5 + }, + { + "month": "2026-01", + "mean": 29.5, + "median": 28.7, + "p10": 25.1, + "p25": 27.1, + "p75": 32.8, + "p90": 34.3, + "n": 5 + }, + { + "month": "2026-02", + "mean": 26.2, + "median": 25.4, + "p10": 22.3, + "p25": 23.8, + "p75": 27.9, + "p90": 30.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 23.0, + "median": 23.0, + "p10": 19.4, + "p25": 21.3, + "p75": 25.4, + "p90": 26.4, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.5, + "median": 29.5, + "p10": 26.1, + "p25": 27.1, + "p75": 31.2, + "p90": 33.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 26.1, + "median": 26.2, + "p10": 21.6, + "p25": 24.6, + "p75": 28.7, + "p90": 30.2, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 21.4, + "median": 20.5, + "std": 6.6, + "min": 5.7, + "max": 50.8, + "p25": 18.4, + "p75": 23.8, + "p85": 24.6, + "p95": 29.9 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 28.7 + }, + { + "date": "2022-10-18", + "value": 13.1 + }, + { + "date": "2023-01-24", + "value": 50.8 + }, + { + "date": "2023-06-15", + "value": 5.7 + }, + { + "date": "2023-09-28", + "value": 32.8 + }, + { + "date": "2024-02-12", + "value": 20.5 + }, + { + "date": "2024-05-07", + "value": 39.4 + }, + { + "date": "2024-09-19", + "value": 9.8 + }, + { + "date": "2025-02-04", + "value": 24.6 + }, + { + "date": "2025-06-10", + "value": 11.5 + }, + { + "date": "2025-09-06", + "value": 24.6 + }, + { + "date": "2025-09-12", + "value": 15.6 + }, + { + "date": "2025-09-18", + "value": 18.0 + }, + { + "date": "2025-09-24", + "value": 18.9 + }, + { + "date": "2025-09-30", + "value": 20.5 + }, + { + "date": "2025-10-04", + "value": 18.9 + }, + { + "date": "2025-10-10", + "value": 20.5 + }, + { + "date": "2025-10-16", + "value": 22.1 + }, + { + "date": "2025-10-22", + "value": 23.8 + }, + { + "date": "2025-10-28", + "value": 25.4 + }, + { + "date": "2025-11-05", + "value": 18.9 + }, + { + "date": "2025-11-11", + "value": 20.5 + }, + { + "date": "2025-11-17", + "value": 22.1 + }, + { + "date": "2025-11-23", + "value": 23.8 + }, + { + "date": "2025-11-29", + "value": 25.4 + }, + { + "date": "2025-12-06", + "value": 18.0 + }, + { + "date": "2025-12-12", + "value": 19.7 + }, + { + "date": "2025-12-18", + "value": 21.3 + }, + { + "date": "2025-12-24", + "value": 23.0 + }, + { + "date": "2025-12-30", + "value": 14.8 + }, + { + "date": "2026-01-04", + "value": 23.0 + }, + { + "date": "2026-01-10", + "value": 24.6 + }, + { + "date": "2026-01-16", + "value": 26.2 + }, + { + "date": "2026-01-22", + "value": 18.0 + }, + { + "date": "2026-01-28", + "value": 19.7 + }, + { + "date": "2026-02-05", + "value": 22.1 + }, + { + "date": "2026-02-11", + "value": 24.6 + }, + { + "date": "2026-02-17", + "value": 15.6 + }, + { + "date": "2026-02-23", + "value": 18.0 + }, + { + "date": "2026-02-29", + "value": 18.9 + }, + { + "date": "2026-03-06", + "value": 27.9 + }, + { + "date": "2026-03-12", + "value": 18.9 + }, + { + "date": "2026-03-18", + "value": 20.5 + }, + { + "date": "2026-03-24", + "value": 22.1 + }, + { + "date": "2026-03-30", + "value": 23.8 + }, + { + "date": "2026-04-04", + "value": 16.4 + }, + { + "date": "2026-04-10", + "value": 18.9 + }, + { + "date": "2026-04-16", + "value": 20.5 + }, + { + "date": "2026-04-22", + "value": 22.1 + }, + { + "date": "2026-04-28", + "value": 23.8 + }, + { + "date": "2026-05-05", + "value": 16.4 + }, + { + "date": "2026-05-11", + "value": 18.0 + }, + { + "date": "2026-05-17", + "value": 19.7 + }, + { + "date": "2026-05-23", + "value": 21.3 + }, + { + "date": "2026-05-29", + "value": 23.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 13.1, + "median": 13.1, + "p10": 13.1, + "p25": 13.1, + "p75": 13.1, + "p90": 13.1, + "n": 1 + }, + { + "month": "2023-01", + "mean": 50.8, + "median": 50.8, + "p10": 50.8, + "p25": 50.8, + "p75": 50.8, + "p90": 50.8, + "n": 1 + }, + { + "month": "2023-06", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 32.8, + "median": 32.8, + "p10": 32.8, + "p25": 32.8, + "p75": 32.8, + "p90": 32.8, + "n": 1 + }, + { + "month": "2024-02", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 39.4, + "median": 39.4, + "p10": 39.4, + "p25": 39.4, + "p75": 39.4, + "p90": 39.4, + "n": 1 + }, + { + "month": "2024-09", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2025-02", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2025-06", + "mean": 11.5, + "median": 11.5, + "p10": 11.5, + "p25": 11.5, + "p75": 11.5, + "p90": 11.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 19.5, + "median": 18.9, + "p10": 16.6, + "p25": 18.0, + "p75": 20.5, + "p90": 23.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 22.1, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 24.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 22.1, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 24.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 19.4, + "median": 19.7, + "p10": 16.1, + "p25": 18.0, + "p75": 21.3, + "p90": 22.3, + "n": 5 + }, + { + "month": "2026-01", + "mean": 22.3, + "median": 23.0, + "p10": 18.7, + "p25": 19.7, + "p75": 24.6, + "p90": 25.6, + "n": 5 + }, + { + "month": "2026-02", + "mean": 19.8, + "median": 18.9, + "p10": 16.6, + "p25": 18.0, + "p75": 22.1, + "p90": 23.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 22.6, + "median": 22.1, + "p10": 19.5, + "p25": 20.5, + "p75": 23.8, + "p90": 26.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 20.3, + "median": 20.5, + "p10": 17.4, + "p25": 18.9, + "p75": 22.1, + "p90": 23.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 19.7, + "median": 19.7, + "p10": 17.1, + "p25": 18.0, + "p75": 21.3, + "p90": 22.3, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 39.6, + "median": 37.7, + "std": 16.2, + "min": 4.1, + "max": 106.6, + "p25": 31.6, + "p75": 44.7, + "p85": 50.0, + "p95": 71.9 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 2.624, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 28.7 + }, + { + "date": "2022-04-15", + "value": 50.8 + }, + { + "date": "2022-04-28", + "value": 14.8 + }, + { + "date": "2022-08-05", + "value": 72.2 + }, + { + "date": "2022-08-12", + "value": 34.4 + }, + { + "date": "2022-08-20", + "value": 45.1 + }, + { + "date": "2022-08-28", + "value": 24.6 + }, + { + "date": "2023-01-10", + "value": 59.0 + }, + { + "date": "2023-01-22", + "value": 20.5 + }, + { + "date": "2023-01-30", + "value": 39.4 + }, + { + "date": "2023-06-05", + "value": 12.3 + }, + { + "date": "2023-06-18", + "value": 77.9 + }, + { + "date": "2023-10-03", + "value": 106.6 + }, + { + "date": "2023-10-10", + "value": 36.9 + }, + { + "date": "2023-10-18", + "value": 31.2 + }, + { + "date": "2023-10-25", + "value": 53.3 + }, + { + "date": "2023-10-30", + "value": 18.0 + }, + { + "date": "2024-03-05", + "value": 64.0 + }, + { + "date": "2024-03-12", + "value": 4.1 + }, + { + "date": "2024-03-20", + "value": 45.1 + }, + { + "date": "2024-03-28", + "value": 32.8 + }, + { + "date": "2024-07-08", + "value": 23.0 + }, + { + "date": "2024-07-15", + "value": 69.7 + }, + { + "date": "2024-07-22", + "value": 41.0 + }, + { + "date": "2024-11-04", + "value": 90.2 + }, + { + "date": "2024-11-11", + "value": 26.2 + }, + { + "date": "2024-11-18", + "value": 55.8 + }, + { + "date": "2024-11-25", + "value": 36.9 + }, + { + "date": "2024-11-30", + "value": 75.4 + }, + { + "date": "2025-03-03", + "value": 16.4 + }, + { + "date": "2025-03-10", + "value": 47.6 + }, + { + "date": "2025-03-17", + "value": 28.7 + }, + { + "date": "2025-03-24", + "value": 34.4 + }, + { + "date": "2025-07-02", + "value": 61.5 + }, + { + "date": "2025-07-09", + "value": 9.8 + }, + { + "date": "2025-07-16", + "value": 39.4 + }, + { + "date": "2025-07-23", + "value": 49.2 + }, + { + "date": "2025-07-30", + "value": 31.2 + }, + { + "date": "2025-09-05", + "value": 40.2 + }, + { + "date": "2025-09-11", + "value": 44.3 + }, + { + "date": "2025-09-17", + "value": 27.9 + }, + { + "date": "2025-09-23", + "value": 32.0 + }, + { + "date": "2025-09-29", + "value": 34.4 + }, + { + "date": "2025-10-06", + "value": 50.0 + }, + { + "date": "2025-10-12", + "value": 33.6 + }, + { + "date": "2025-10-18", + "value": 37.7 + }, + { + "date": "2025-10-24", + "value": 40.2 + }, + { + "date": "2025-10-30", + "value": 43.5 + }, + { + "date": "2025-11-04", + "value": 29.5 + }, + { + "date": "2025-11-10", + "value": 33.6 + }, + { + "date": "2025-11-16", + "value": 36.1 + }, + { + "date": "2025-11-22", + "value": 39.4 + }, + { + "date": "2025-11-28", + "value": 42.6 + }, + { + "date": "2025-12-05", + "value": 29.5 + }, + { + "date": "2025-12-11", + "value": 32.0 + }, + { + "date": "2025-12-17", + "value": 35.3 + }, + { + "date": "2025-12-23", + "value": 38.5 + }, + { + "date": "2025-12-29", + "value": 41.8 + }, + { + "date": "2026-01-06", + "value": 38.5 + }, + { + "date": "2026-01-12", + "value": 41.0 + }, + { + "date": "2026-01-18", + "value": 44.3 + }, + { + "date": "2026-01-24", + "value": 47.6 + }, + { + "date": "2026-01-30", + "value": 32.0 + }, + { + "date": "2026-02-04", + "value": 36.9 + }, + { + "date": "2026-02-10", + "value": 40.2 + }, + { + "date": "2026-02-16", + "value": 44.3 + }, + { + "date": "2026-02-22", + "value": 27.9 + }, + { + "date": "2026-02-28", + "value": 32.0 + }, + { + "date": "2026-03-05", + "value": 45.9 + }, + { + "date": "2026-03-11", + "value": 50.0 + }, + { + "date": "2026-03-17", + "value": 33.6 + }, + { + "date": "2026-03-23", + "value": 37.7 + }, + { + "date": "2026-03-29", + "value": 40.2 + }, + { + "date": "2026-04-06", + "value": 45.9 + }, + { + "date": "2026-04-12", + "value": 29.5 + }, + { + "date": "2026-04-18", + "value": 33.6 + }, + { + "date": "2026-04-24", + "value": 36.1 + }, + { + "date": "2026-04-30", + "value": 39.4 + }, + { + "date": "2026-05-04", + "value": 26.2 + }, + { + "date": "2026-05-10", + "value": 29.5 + }, + { + "date": "2026-05-16", + "value": 32.0 + }, + { + "date": "2026-05-22", + "value": 35.3 + }, + { + "date": "2026-05-28", + "value": 38.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 31.4, + "median": 28.7, + "p10": 17.5, + "p25": 21.7, + "p75": 39.8, + "p90": 46.4, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 44.1, + "median": 39.8, + "p10": 27.6, + "p25": 32.0, + "p75": 51.9, + "p90": 64.0, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 39.6, + "median": 39.4, + "p10": 24.3, + "p25": 29.9, + "p75": 49.2, + "p90": 55.1, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 45.1, + "median": 45.1, + "p10": 18.9, + "p25": 28.7, + "p75": 61.5, + "p90": 71.3, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 49.2, + "median": 36.9, + "p10": 23.3, + "p25": 31.2, + "p75": 53.3, + "p90": 85.3, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 36.5, + "median": 38.9, + "p10": 12.7, + "p25": 25.7, + "p75": 49.9, + "p90": 58.3, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 44.5, + "median": 41.0, + "p10": 26.6, + "p25": 32.0, + "p75": 55.3, + "p90": 64.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 56.9, + "median": 55.8, + "p10": 30.5, + "p25": 36.9, + "p75": 75.4, + "p90": 84.3, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 31.8, + "median": 31.6, + "p10": 20.1, + "p25": 25.7, + "p75": 37.7, + "p90": 43.6, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 38.2, + "median": 39.4, + "p10": 18.4, + "p25": 31.2, + "p75": 49.2, + "p90": 56.6, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 35.8, + "median": 34.4, + "p10": 29.5, + "p25": 32.0, + "p75": 40.2, + "p90": 42.6, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 41.0, + "median": 40.2, + "p10": 35.3, + "p25": 37.7, + "p75": 43.5, + "p90": 47.4, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 36.2, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 35.4, + "median": 35.3, + "p10": 30.5, + "p25": 32.0, + "p75": 38.5, + "p90": 40.5, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 40.7, + "median": 41.0, + "p10": 34.6, + "p25": 38.5, + "p75": 44.3, + "p90": 46.2, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 36.2, + "median": 36.9, + "p10": 29.5, + "p25": 32.0, + "p75": 40.2, + "p90": 42.6, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 41.5, + "median": 40.2, + "p10": 35.3, + "p25": 37.7, + "p75": 45.9, + "p90": 48.4, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 36.9, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 39.4, + "p90": 43.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 32.3, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 35.3, + "p90": 37.2, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 30.0, + "median": 27.9, + "std": 13.0, + "min": 2.5, + "max": 80.4, + "p25": 23.0, + "p75": 33.6, + "p85": 36.9, + "p95": 56.7 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 1.476, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 23.0 + }, + { + "date": "2022-05-10", + "value": 36.9 + }, + { + "date": "2022-05-18", + "value": 9.8 + }, + { + "date": "2022-05-25", + "value": 50.8 + }, + { + "date": "2023-02-06", + "value": 27.1 + }, + { + "date": "2023-02-14", + "value": 64.0 + }, + { + "date": "2023-02-22", + "value": 16.4 + }, + { + "date": "2023-02-28", + "value": 45.1 + }, + { + "date": "2023-09-05", + "value": 6.6 + }, + { + "date": "2023-09-15", + "value": 34.4 + }, + { + "date": "2023-09-25", + "value": 53.3 + }, + { + "date": "2024-04-03", + "value": 31.2 + }, + { + "date": "2024-04-10", + "value": 12.3 + }, + { + "date": "2024-04-17", + "value": 59.0 + }, + { + "date": "2024-04-24", + "value": 20.5 + }, + { + "date": "2024-10-02", + "value": 39.4 + }, + { + "date": "2024-10-09", + "value": 2.5 + }, + { + "date": "2024-10-16", + "value": 69.7 + }, + { + "date": "2024-10-23", + "value": 24.6 + }, + { + "date": "2024-10-30", + "value": 45.1 + }, + { + "date": "2025-04-07", + "value": 18.0 + }, + { + "date": "2025-04-14", + "value": 32.8 + }, + { + "date": "2025-04-21", + "value": 80.4 + }, + { + "date": "2025-04-28", + "value": 14.8 + }, + { + "date": "2025-09-04", + "value": 32.0 + }, + { + "date": "2025-09-10", + "value": 33.6 + }, + { + "date": "2025-09-16", + "value": 36.9 + }, + { + "date": "2025-09-22", + "value": 24.6 + }, + { + "date": "2025-09-28", + "value": 27.9 + }, + { + "date": "2025-10-05", + "value": 31.2 + }, + { + "date": "2025-10-11", + "value": 33.6 + }, + { + "date": "2025-10-17", + "value": 22.1 + }, + { + "date": "2025-10-23", + "value": 24.6 + }, + { + "date": "2025-10-29", + "value": 26.2 + }, + { + "date": "2025-11-06", + "value": 31.2 + }, + { + "date": "2025-11-12", + "value": 18.9 + }, + { + "date": "2025-11-18", + "value": 22.1 + }, + { + "date": "2025-11-24", + "value": 23.8 + }, + { + "date": "2025-11-30", + "value": 26.2 + }, + { + "date": "2025-12-04", + "value": 23.0 + }, + { + "date": "2025-12-10", + "value": 26.2 + }, + { + "date": "2025-12-16", + "value": 27.9 + }, + { + "date": "2025-12-22", + "value": 30.3 + }, + { + "date": "2025-12-28", + "value": 32.8 + }, + { + "date": "2026-01-05", + "value": 23.0 + }, + { + "date": "2026-01-11", + "value": 25.4 + }, + { + "date": "2026-01-17", + "value": 27.1 + }, + { + "date": "2026-01-23", + "value": 29.5 + }, + { + "date": "2026-01-29", + "value": 32.0 + }, + { + "date": "2026-02-06", + "value": 29.5 + }, + { + "date": "2026-02-12", + "value": 32.0 + }, + { + "date": "2026-02-18", + "value": 33.6 + }, + { + "date": "2026-02-24", + "value": 36.9 + }, + { + "date": "2026-02-30", + "value": 24.6 + }, + { + "date": "2026-03-04", + "value": 28.7 + }, + { + "date": "2026-03-10", + "value": 31.2 + }, + { + "date": "2026-03-16", + "value": 33.6 + }, + { + "date": "2026-03-22", + "value": 22.1 + }, + { + "date": "2026-03-28", + "value": 24.6 + }, + { + "date": "2026-04-05", + "value": 27.9 + }, + { + "date": "2026-04-11", + "value": 31.2 + }, + { + "date": "2026-04-17", + "value": 18.9 + }, + { + "date": "2026-04-23", + "value": 22.1 + }, + { + "date": "2026-04-29", + "value": 23.8 + }, + { + "date": "2026-05-06", + "value": 35.3 + }, + { + "date": "2026-05-12", + "value": 23.0 + }, + { + "date": "2026-05-18", + "value": 26.2 + }, + { + "date": "2026-05-24", + "value": 27.9 + }, + { + "date": "2026-05-30", + "value": 30.3 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 30.2, + "median": 29.9, + "p10": 13.8, + "p25": 19.7, + "p75": 40.4, + "p90": 46.7, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 38.1, + "median": 36.1, + "p10": 19.6, + "p25": 24.4, + "p75": 49.9, + "p90": 58.3, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 31.4, + "median": 34.4, + "p10": 12.1, + "p25": 20.5, + "p75": 43.9, + "p90": 49.5, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 30.7, + "median": 25.8, + "p10": 14.8, + "p25": 18.4, + "p75": 38.1, + "p90": 50.7, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 36.2, + "median": 39.4, + "p10": 11.3, + "p25": 24.6, + "p75": 45.1, + "p90": 59.9, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 36.5, + "median": 25.4, + "p10": 15.7, + "p25": 17.2, + "p75": 44.7, + "p90": 66.1, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 31.0, + "median": 32.0, + "p10": 25.9, + "p25": 27.9, + "p75": 33.6, + "p90": 35.6, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 27.6, + "median": 26.2, + "p10": 23.1, + "p25": 24.6, + "p75": 31.2, + "p90": 32.6, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 24.4, + "median": 23.8, + "p10": 20.2, + "p25": 22.1, + "p75": 26.2, + "p90": 29.2, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 28.0, + "median": 27.9, + "p10": 24.3, + "p25": 26.2, + "p75": 30.3, + "p90": 31.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 27.4, + "median": 27.1, + "p10": 23.9, + "p25": 25.4, + "p75": 29.5, + "p90": 31.0, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 31.3, + "median": 32.0, + "p10": 26.6, + "p25": 29.5, + "p75": 33.6, + "p90": 35.6, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 28.0, + "median": 28.7, + "p10": 23.1, + "p25": 24.6, + "p75": 31.2, + "p90": 32.6, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 24.8, + "median": 23.8, + "p10": 20.2, + "p25": 22.1, + "p75": 27.9, + "p90": 29.8, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 28.5, + "median": 27.9, + "p10": 24.3, + "p25": 26.2, + "p75": 30.3, + "p90": 33.3, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 36.0, + "median": 33.6, + "std": 15.7, + "min": 3.3, + "max": 94.3, + "p25": 28.1, + "p75": 41.0, + "p85": 44.3, + "p95": 67.2 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 4.51, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 32.8 + }, + { + "date": "2022-06-15", + "value": 18.0 + }, + { + "date": "2022-06-25", + "value": 55.8 + }, + { + "date": "2023-03-08", + "value": 3.3 + }, + { + "date": "2023-03-15", + "value": 45.1 + }, + { + "date": "2023-03-22", + "value": 94.3 + }, + { + "date": "2023-03-29", + "value": 24.6 + }, + { + "date": "2023-11-06", + "value": 50.8 + }, + { + "date": "2023-11-13", + "value": 14.8 + }, + { + "date": "2023-11-20", + "value": 69.7 + }, + { + "date": "2024-06-03", + "value": 28.7 + }, + { + "date": "2024-06-10", + "value": 59.0 + }, + { + "date": "2024-06-17", + "value": 8.2 + }, + { + "date": "2024-06-24", + "value": 39.4 + }, + { + "date": "2024-06-30", + "value": 77.9 + }, + { + "date": "2025-01-07", + "value": 23.0 + }, + { + "date": "2025-01-14", + "value": 42.6 + }, + { + "date": "2025-01-21", + "value": 12.3 + }, + { + "date": "2025-01-28", + "value": 64.0 + }, + { + "date": "2025-08-04", + "value": 34.4 + }, + { + "date": "2025-08-08", + "value": 6.6 + }, + { + "date": "2025-08-12", + "value": 53.3 + }, + { + "date": "2025-08-16", + "value": 27.1 + }, + { + "date": "2025-08-20", + "value": 82.0 + }, + { + "date": "2025-08-24", + "value": 16.4 + }, + { + "date": "2025-09-06", + "value": 33.6 + }, + { + "date": "2025-09-12", + "value": 36.9 + }, + { + "date": "2025-09-18", + "value": 39.4 + }, + { + "date": "2025-09-24", + "value": 42.6 + }, + { + "date": "2025-09-30", + "value": 27.9 + }, + { + "date": "2025-10-04", + "value": 32.8 + }, + { + "date": "2025-10-10", + "value": 36.1 + }, + { + "date": "2025-10-16", + "value": 39.4 + }, + { + "date": "2025-10-22", + "value": 24.6 + }, + { + "date": "2025-10-28", + "value": 27.9 + }, + { + "date": "2025-11-05", + "value": 41.0 + }, + { + "date": "2025-11-11", + "value": 44.3 + }, + { + "date": "2025-11-17", + "value": 29.5 + }, + { + "date": "2025-11-23", + "value": 33.6 + }, + { + "date": "2025-11-29", + "value": 36.1 + }, + { + "date": "2025-12-06", + "value": 41.0 + }, + { + "date": "2025-12-12", + "value": 26.2 + }, + { + "date": "2025-12-18", + "value": 29.5 + }, + { + "date": "2025-12-24", + "value": 32.0 + }, + { + "date": "2025-12-30", + "value": 35.3 + }, + { + "date": "2026-01-04", + "value": 23.0 + }, + { + "date": "2026-01-10", + "value": 26.2 + }, + { + "date": "2026-01-16", + "value": 28.7 + }, + { + "date": "2026-01-22", + "value": 31.2 + }, + { + "date": "2026-01-28", + "value": 34.4 + }, + { + "date": "2026-02-05", + "value": 32.0 + }, + { + "date": "2026-02-11", + "value": 33.6 + }, + { + "date": "2026-02-17", + "value": 36.9 + }, + { + "date": "2026-02-23", + "value": 39.4 + }, + { + "date": "2026-02-29", + "value": 42.6 + }, + { + "date": "2026-03-06", + "value": 30.3 + }, + { + "date": "2026-03-12", + "value": 32.8 + }, + { + "date": "2026-03-18", + "value": 36.1 + }, + { + "date": "2026-03-24", + "value": 39.4 + }, + { + "date": "2026-03-30", + "value": 24.6 + }, + { + "date": "2026-04-04", + "value": 38.5 + }, + { + "date": "2026-04-10", + "value": 41.0 + }, + { + "date": "2026-04-16", + "value": 44.3 + }, + { + "date": "2026-04-22", + "value": 29.5 + }, + { + "date": "2026-04-28", + "value": 33.6 + }, + { + "date": "2026-05-05", + "value": 37.7 + }, + { + "date": "2026-05-11", + "value": 41.0 + }, + { + "date": "2026-05-17", + "value": 26.2 + }, + { + "date": "2026-05-23", + "value": 29.5 + }, + { + "date": "2026-05-29", + "value": 32.0 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 35.5, + "median": 32.8, + "p10": 21.0, + "p25": 25.4, + "p75": 44.3, + "p90": 51.2, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 41.8, + "median": 34.9, + "p10": 9.7, + "p25": 19.3, + "p75": 57.4, + "p90": 79.5, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 45.1, + "median": 50.8, + "p10": 22.0, + "p25": 32.8, + "p75": 60.3, + "p90": 65.9, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 42.6, + "median": 39.4, + "p10": 16.4, + "p25": 28.7, + "p75": 59.0, + "p90": 70.4, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 35.5, + "median": 32.8, + "p10": 15.5, + "p25": 20.3, + "p75": 48.0, + "p90": 57.6, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 36.7, + "median": 30.7, + "p10": 11.5, + "p25": 19.1, + "p75": 48.6, + "p90": 67.6, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 36.1, + "median": 36.9, + "p10": 30.2, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 32.1, + "median": 32.8, + "p10": 25.9, + "p25": 27.9, + "p75": 36.1, + "p90": 38.0, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 36.9, + "median": 36.1, + "p10": 31.2, + "p25": 33.6, + "p75": 41.0, + "p90": 43.0, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 32.8, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 35.3, + "p90": 38.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 28.7, + "median": 28.7, + "p10": 24.3, + "p25": 26.2, + "p75": 31.2, + "p90": 33.1, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 36.9, + "median": 36.9, + "p10": 32.6, + "p25": 33.6, + "p75": 39.4, + "p90": 41.3, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 32.6, + "median": 32.8, + "p10": 26.9, + "p25": 30.3, + "p75": 36.1, + "p90": 38.0, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 37.4, + "median": 38.5, + "p10": 31.2, + "p25": 33.6, + "p75": 41.0, + "p90": 43.0, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 33.3, + "median": 32.0, + "p10": 27.6, + "p25": 29.5, + "p75": 37.7, + "p90": 39.7, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 3.6, + "median": 3.3, + "std": 1.5, + "min": 0.8, + "max": 11.5, + "p25": 2.7, + "p75": 4.1, + "p85": 4.1, + "p95": 5.4 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 2.5 + }, + { + "date": "2022-07-05", + "value": 4.1 + }, + { + "date": "2022-10-12", + "value": 1.6 + }, + { + "date": "2023-01-20", + "value": 5.7 + }, + { + "date": "2023-04-15", + "value": 3.3 + }, + { + "date": "2023-07-28", + "value": 4.9 + }, + { + "date": "2023-10-05", + "value": 2.5 + }, + { + "date": "2024-01-12", + "value": 11.5 + }, + { + "date": "2024-04-22", + "value": 3.3 + }, + { + "date": "2024-07-10", + "value": 6.6 + }, + { + "date": "2024-10-18", + "value": 2.5 + }, + { + "date": "2025-01-25", + "value": 4.1 + }, + { + "date": "2025-05-08", + "value": 0.8 + }, + { + "date": "2025-08-15", + "value": 4.9 + }, + { + "date": "2025-09-04", + "value": 2.5 + }, + { + "date": "2025-09-10", + "value": 3.3 + }, + { + "date": "2025-09-16", + "value": 3.3 + }, + { + "date": "2025-09-22", + "value": 3.3 + }, + { + "date": "2025-10-05", + "value": 2.5 + }, + { + "date": "2025-10-11", + "value": 3.3 + }, + { + "date": "2025-10-17", + "value": 3.3 + }, + { + "date": "2025-10-23", + "value": 3.3 + }, + { + "date": "2025-11-06", + "value": 3.3 + }, + { + "date": "2025-11-12", + "value": 4.1 + }, + { + "date": "2025-11-18", + "value": 4.1 + }, + { + "date": "2025-11-24", + "value": 4.1 + }, + { + "date": "2025-12-04", + "value": 3.3 + }, + { + "date": "2025-12-10", + "value": 4.1 + }, + { + "date": "2025-12-16", + "value": 4.1 + }, + { + "date": "2025-12-22", + "value": 2.5 + }, + { + "date": "2026-01-05", + "value": 3.3 + }, + { + "date": "2026-01-11", + "value": 4.1 + }, + { + "date": "2026-01-17", + "value": 2.5 + }, + { + "date": "2026-01-23", + "value": 2.5 + }, + { + "date": "2026-02-06", + "value": 4.1 + }, + { + "date": "2026-02-12", + "value": 2.5 + }, + { + "date": "2026-02-18", + "value": 3.3 + }, + { + "date": "2026-02-24", + "value": 3.3 + }, + { + "date": "2026-03-04", + "value": 2.5 + }, + { + "date": "2026-03-10", + "value": 2.5 + }, + { + "date": "2026-03-16", + "value": 3.3 + }, + { + "date": "2026-03-22", + "value": 3.3 + }, + { + "date": "2026-04-05", + "value": 3.3 + }, + { + "date": "2026-04-11", + "value": 3.3 + }, + { + "date": "2026-04-17", + "value": 4.1 + }, + { + "date": "2026-04-23", + "value": 4.1 + }, + { + "date": "2026-05-06", + "value": 3.3 + }, + { + "date": "2026-05-12", + "value": 3.3 + }, + { + "date": "2026-05-18", + "value": 4.1 + }, + { + "date": "2026-05-24", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-10", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2023-10", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 11.5, + "median": 11.5, + "p10": 11.5, + "p25": 11.5, + "p75": 11.5, + "p90": 11.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2024-10", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-05", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.9, + "median": 4.1, + "p10": 3.5, + "p25": 3.9, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.5, + "median": 3.7, + "p10": 2.7, + "p25": 3.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.1, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.5, + "p90": 3.9, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.3, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.5, + "p90": 3.9, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.7, + "median": 3.7, + "p10": 3.3, + "p25": 3.3, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.7, + "median": 3.7, + "p10": 3.3, + "p25": 3.3, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 14.3, + "median": 13.1, + "std": 7.4, + "min": 1.6, + "max": 45.1, + "p25": 10.7, + "p75": 15.6, + "p85": 16.7, + "p95": 30.3 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 10.25, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 9.8 + }, + { + "date": "2022-05-15", + "value": 20.5 + }, + { + "date": "2022-05-22", + "value": 6.6 + }, + { + "date": "2022-11-03", + "value": 28.7 + }, + { + "date": "2022-11-10", + "value": 12.3 + }, + { + "date": "2022-11-18", + "value": 4.1 + }, + { + "date": "2022-11-25", + "value": 18.0 + }, + { + "date": "2023-05-08", + "value": 14.8 + }, + { + "date": "2023-05-15", + "value": 32.8 + }, + { + "date": "2023-05-22", + "value": 8.2 + }, + { + "date": "2023-11-06", + "value": 45.1 + }, + { + "date": "2023-11-13", + "value": 1.6 + }, + { + "date": "2023-11-20", + "value": 23.0 + }, + { + "date": "2023-11-27", + "value": 12.3 + }, + { + "date": "2023-11-30", + "value": 6.6 + }, + { + "date": "2024-05-06", + "value": 16.4 + }, + { + "date": "2024-05-13", + "value": 36.9 + }, + { + "date": "2024-05-20", + "value": 9.8 + }, + { + "date": "2024-05-27", + "value": 2.5 + }, + { + "date": "2024-11-04", + "value": 14.8 + }, + { + "date": "2024-11-11", + "value": 24.6 + }, + { + "date": "2024-11-18", + "value": 6.6 + }, + { + "date": "2025-05-05", + "value": 18.0 + }, + { + "date": "2025-05-09", + "value": 28.7 + }, + { + "date": "2025-05-13", + "value": 4.1 + }, + { + "date": "2025-05-17", + "value": 12.3 + }, + { + "date": "2025-05-21", + "value": 34.4 + }, + { + "date": "2025-05-25", + "value": 8.2 + }, + { + "date": "2025-09-05", + "value": 11.5 + }, + { + "date": "2025-09-11", + "value": 13.1 + }, + { + "date": "2025-09-17", + "value": 13.9 + }, + { + "date": "2025-09-23", + "value": 14.8 + }, + { + "date": "2025-09-29", + "value": 15.6 + }, + { + "date": "2025-10-06", + "value": 11.5 + }, + { + "date": "2025-10-12", + "value": 12.3 + }, + { + "date": "2025-10-18", + "value": 13.1 + }, + { + "date": "2025-10-24", + "value": 14.8 + }, + { + "date": "2025-10-30", + "value": 9.0 + }, + { + "date": "2025-11-04", + "value": 14.8 + }, + { + "date": "2025-11-10", + "value": 15.6 + }, + { + "date": "2025-11-16", + "value": 16.4 + }, + { + "date": "2025-11-22", + "value": 11.5 + }, + { + "date": "2025-11-28", + "value": 12.3 + }, + { + "date": "2025-12-05", + "value": 13.9 + }, + { + "date": "2025-12-11", + "value": 15.6 + }, + { + "date": "2025-12-17", + "value": 9.8 + }, + { + "date": "2025-12-23", + "value": 11.5 + }, + { + "date": "2025-12-29", + "value": 12.3 + }, + { + "date": "2026-01-06", + "value": 13.9 + }, + { + "date": "2026-01-12", + "value": 9.0 + }, + { + "date": "2026-01-18", + "value": 9.8 + }, + { + "date": "2026-01-24", + "value": 10.7 + }, + { + "date": "2026-01-30", + "value": 11.5 + }, + { + "date": "2026-02-04", + "value": 10.7 + }, + { + "date": "2026-02-10", + "value": 11.5 + }, + { + "date": "2026-02-16", + "value": 13.1 + }, + { + "date": "2026-02-22", + "value": 13.9 + }, + { + "date": "2026-02-28", + "value": 14.8 + }, + { + "date": "2026-03-05", + "value": 10.7 + }, + { + "date": "2026-03-11", + "value": 11.5 + }, + { + "date": "2026-03-17", + "value": 12.3 + }, + { + "date": "2026-03-23", + "value": 13.1 + }, + { + "date": "2026-03-29", + "value": 14.8 + }, + { + "date": "2026-04-06", + "value": 13.1 + }, + { + "date": "2026-04-12", + "value": 14.8 + }, + { + "date": "2026-04-18", + "value": 15.6 + }, + { + "date": "2026-04-24", + "value": 16.4 + }, + { + "date": "2026-04-30", + "value": 11.5 + }, + { + "date": "2026-05-04", + "value": 13.1 + }, + { + "date": "2026-05-10", + "value": 13.9 + }, + { + "date": "2026-05-16", + "value": 15.6 + }, + { + "date": "2026-05-22", + "value": 9.8 + }, + { + "date": "2026-05-28", + "value": 11.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 12.3, + "median": 9.8, + "p10": 7.2, + "p25": 8.2, + "p75": 15.2, + "p90": 18.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 15.8, + "median": 15.2, + "p10": 6.6, + "p25": 10.2, + "p75": 20.7, + "p90": 25.5, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 18.6, + "median": 14.8, + "p10": 9.5, + "p25": 11.5, + "p75": 23.8, + "p90": 29.2, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 17.7, + "median": 12.3, + "p10": 3.6, + "p25": 6.6, + "p75": 23.0, + "p90": 36.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 16.4, + "median": 13.1, + "p10": 4.7, + "p25": 8.0, + "p75": 21.6, + "p90": 30.7, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 15.3, + "median": 14.8, + "p10": 8.2, + "p25": 10.7, + "p75": 19.7, + "p90": 22.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 17.6, + "median": 15.2, + "p10": 6.1, + "p25": 9.3, + "p75": 26.1, + "p90": 31.6, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 13.8, + "median": 13.9, + "p10": 12.1, + "p25": 13.1, + "p75": 14.8, + "p90": 15.3, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 12.1, + "median": 12.3, + "p10": 10.0, + "p25": 11.5, + "p75": 13.1, + "p90": 14.1, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 14.1, + "median": 14.8, + "p10": 11.8, + "p25": 12.3, + "p75": 15.6, + "p90": 16.1, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 12.6, + "median": 12.3, + "p10": 10.5, + "p25": 11.5, + "p75": 13.9, + "p90": 14.9, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 11.0, + "median": 10.7, + "p10": 9.3, + "p25": 9.8, + "p75": 11.5, + "p90": 13.0, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 12.8, + "median": 13.1, + "p10": 11.0, + "p25": 11.5, + "p75": 13.9, + "p90": 14.4, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 12.5, + "median": 12.3, + "p10": 11.0, + "p25": 11.5, + "p75": 13.1, + "p90": 14.1, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 14.3, + "median": 14.8, + "p10": 12.1, + "p25": 13.1, + "p75": 15.6, + "p90": 16.1, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 12.8, + "median": 13.1, + "p10": 10.5, + "p25": 11.5, + "p75": 13.9, + "p90": 14.9, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 2.6, + "median": 2.5, + "std": 1.1, + "min": 0.0, + "max": 8.2, + "p25": 2.5, + "p75": 3.3, + "p85": 3.3, + "p95": 4.3 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 1.6 + }, + { + "date": "2022-06-10", + "value": 2.5 + }, + { + "date": "2022-07-15", + "value": 0.8 + }, + { + "date": "2022-08-22", + "value": 3.3 + }, + { + "date": "2022-10-05", + "value": 1.6 + }, + { + "date": "2022-11-18", + "value": 4.1 + }, + { + "date": "2023-01-10", + "value": 2.5 + }, + { + "date": "2023-03-25", + "value": 5.7 + }, + { + "date": "2023-05-12", + "value": 1.6 + }, + { + "date": "2023-07-08", + "value": 3.3 + }, + { + "date": "2023-09-15", + "value": 0.8 + }, + { + "date": "2023-11-22", + "value": 2.5 + }, + { + "date": "2024-01-18", + "value": 8.2 + }, + { + "date": "2024-03-08", + "value": 2.5 + }, + { + "date": "2024-05-15", + "value": 1.6 + }, + { + "date": "2024-07-22", + "value": 4.1 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 3.3 + }, + { + "date": "2025-01-15", + "value": 2.5 + }, + { + "date": "2025-03-20", + "value": 1.6 + }, + { + "date": "2025-05-28", + "value": 4.9 + }, + { + "date": "2025-08-05", + "value": 2.5 + }, + { + "date": "2025-09-05", + "value": 3.3 + }, + { + "date": "2025-09-11", + "value": 3.3 + }, + { + "date": "2025-09-17", + "value": 2.5 + }, + { + "date": "2025-09-23", + "value": 2.5 + }, + { + "date": "2025-10-06", + "value": 3.3 + }, + { + "date": "2025-10-12", + "value": 1.6 + }, + { + "date": "2025-10-18", + "value": 2.5 + }, + { + "date": "2025-10-24", + "value": 2.5 + }, + { + "date": "2025-11-04", + "value": 1.6 + }, + { + "date": "2025-11-10", + "value": 1.6 + }, + { + "date": "2025-11-16", + "value": 2.5 + }, + { + "date": "2025-11-22", + "value": 2.5 + }, + { + "date": "2025-12-05", + "value": 2.5 + }, + { + "date": "2025-12-11", + "value": 2.5 + }, + { + "date": "2025-12-17", + "value": 2.5 + }, + { + "date": "2025-12-23", + "value": 3.3 + }, + { + "date": "2026-01-06", + "value": 2.5 + }, + { + "date": "2026-01-12", + "value": 2.5 + }, + { + "date": "2026-01-18", + "value": 2.5 + }, + { + "date": "2026-01-24", + "value": 3.3 + }, + { + "date": "2026-02-04", + "value": 3.3 + }, + { + "date": "2026-02-10", + "value": 3.3 + }, + { + "date": "2026-02-16", + "value": 3.3 + }, + { + "date": "2026-02-22", + "value": 2.5 + }, + { + "date": "2026-03-05", + "value": 2.5 + }, + { + "date": "2026-03-11", + "value": 3.3 + }, + { + "date": "2026-03-17", + "value": 1.6 + }, + { + "date": "2026-03-23", + "value": 2.5 + }, + { + "date": "2026-04-06", + "value": 2.5 + }, + { + "date": "2026-04-12", + "value": 1.6 + }, + { + "date": "2026-04-18", + "value": 1.6 + }, + { + "date": "2026-04-24", + "value": 2.5 + }, + { + "date": "2026-05-04", + "value": 2.5 + }, + { + "date": "2026-05-10", + "value": 2.5 + }, + { + "date": "2026-05-16", + "value": 2.5 + }, + { + "date": "2026-05-22", + "value": 2.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-06", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2022-10", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2023-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-07", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-09", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2023-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1 + }, + { + "month": "2024-03", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2024-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2025-05", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2025-08", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-10", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.0, + "median": 2.0, + "p10": 1.6, + "p25": 1.6, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.1, + "median": 3.3, + "p10": 2.7, + "p25": 3.1, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.0, + "median": 2.0, + "p10": 1.6, + "p25": 1.6, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 2.8, + "median": 2.5, + "std": 1.5, + "min": 0.0, + "max": 10.7, + "p25": 2.5, + "p75": 3.3, + "p85": 3.3, + "p95": 5.1 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 1.6 + }, + { + "date": "2022-06-13", + "value": 0.8 + }, + { + "date": "2022-07-16", + "value": 2.5 + }, + { + "date": "2022-08-26", + "value": 1.6 + }, + { + "date": "2022-10-07", + "value": 4.1 + }, + { + "date": "2022-11-23", + "value": 1.6 + }, + { + "date": "2023-01-13", + "value": 3.3 + }, + { + "date": "2023-04-01", + "value": 2.5 + }, + { + "date": "2023-05-14", + "value": 4.9 + }, + { + "date": "2023-07-12", + "value": 1.6 + }, + { + "date": "2023-09-16", + "value": 10.7 + }, + { + "date": "2023-11-25", + "value": 2.5 + }, + { + "date": "2024-01-28", + "value": 5.7 + }, + { + "date": "2024-03-11", + "value": 0.8 + }, + { + "date": "2024-05-17", + "value": 3.3 + }, + { + "date": "2024-07-27", + "value": 4.1 + }, + { + "date": "2024-09-10", + "value": 1.6 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 2.5 + }, + { + "date": "2025-03-22", + "value": 6.6 + }, + { + "date": "2025-06-03", + "value": 1.6 + }, + { + "date": "2025-08-08", + "value": 4.1 + }, + { + "date": "2025-09-04", + "value": 1.6 + }, + { + "date": "2025-09-10", + "value": 2.5 + }, + { + "date": "2025-09-16", + "value": 2.5 + }, + { + "date": "2025-09-22", + "value": 2.5 + }, + { + "date": "2025-10-05", + "value": 2.5 + }, + { + "date": "2025-10-11", + "value": 2.5 + }, + { + "date": "2025-10-17", + "value": 3.3 + }, + { + "date": "2025-10-23", + "value": 3.3 + }, + { + "date": "2025-11-06", + "value": 2.5 + }, + { + "date": "2025-11-12", + "value": 2.5 + }, + { + "date": "2025-11-18", + "value": 2.5 + }, + { + "date": "2025-11-24", + "value": 3.3 + }, + { + "date": "2025-12-04", + "value": 2.5 + }, + { + "date": "2025-12-10", + "value": 2.5 + }, + { + "date": "2025-12-16", + "value": 2.5 + }, + { + "date": "2025-12-22", + "value": 1.6 + }, + { + "date": "2026-01-05", + "value": 3.3 + }, + { + "date": "2026-01-11", + "value": 3.3 + }, + { + "date": "2026-01-17", + "value": 2.5 + }, + { + "date": "2026-01-23", + "value": 2.5 + }, + { + "date": "2026-02-06", + "value": 3.3 + }, + { + "date": "2026-02-12", + "value": 1.6 + }, + { + "date": "2026-02-18", + "value": 2.5 + }, + { + "date": "2026-02-24", + "value": 2.5 + }, + { + "date": "2026-03-04", + "value": 2.5 + }, + { + "date": "2026-03-10", + "value": 2.5 + }, + { + "date": "2026-03-16", + "value": 2.5 + }, + { + "date": "2026-03-22", + "value": 3.3 + }, + { + "date": "2026-04-05", + "value": 2.5 + }, + { + "date": "2026-04-11", + "value": 2.5 + }, + { + "date": "2026-04-17", + "value": 2.5 + }, + { + "date": "2026-04-23", + "value": 2.5 + }, + { + "date": "2026-05-06", + "value": 2.5 + }, + { + "date": "2026-05-12", + "value": 2.5 + }, + { + "date": "2026-05-18", + "value": 2.5 + }, + { + "date": "2026-05-24", + "value": 2.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-06", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2022-07", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2022-08", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2022-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-11", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2023-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 4.9, + "median": 4.9, + "p10": 4.9, + "p25": 4.9, + "p75": 4.9, + "p90": 4.9, + "n": 1 + }, + { + "month": "2023-07", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2023-09", + "mean": 10.7, + "median": 10.7, + "p10": 10.7, + "p25": 10.7, + "p75": 10.7, + "p90": 10.7, + "n": 1 + }, + { + "month": "2023-11", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 5.7, + "median": 5.7, + "p10": 5.7, + "p25": 5.7, + "p75": 5.7, + "p90": 5.7, + "n": 1 + }, + { + "month": "2024-03", + "mean": 0.8, + "median": 0.8, + "p10": 0.8, + "p25": 0.8, + "p75": 0.8, + "p90": 0.8, + "n": 1 + }, + { + "month": "2024-05", + "mean": 3.3, + "median": 3.3, + "p10": 3.3, + "p25": 3.3, + "p75": 3.3, + "p90": 3.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-09", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 6.6, + "median": 6.6, + "p10": 6.6, + "p25": 6.6, + "p75": 6.6, + "p90": 6.6, + "n": 1 + }, + { + "month": "2025-06", + "mean": 1.6, + "median": 1.6, + "p10": 1.6, + "p25": 1.6, + "p75": 1.6, + "p90": 1.6, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 2.3, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 2.3, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-01", + "mean": 2.9, + "median": 2.9, + "p10": 2.5, + "p25": 2.5, + "p75": 3.3, + "p90": 3.3, + "n": 4 + }, + { + "month": "2026-02", + "mean": 2.5, + "median": 2.5, + "p10": 1.9, + "p25": 2.3, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 2.7, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.7, + "p90": 3.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 2.5, + "median": 2.5, + "p10": 2.5, + "p25": 2.5, + "p75": 2.5, + "p90": 2.5, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 10.4, + "median": 9.8, + "std": 4.6, + "min": 1.6, + "max": 34.4, + "p25": 8.2, + "p75": 11.5, + "p85": 12.3, + "p95": 16.7 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 23.37, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 6.6 + }, + { + "date": "2023-03-25", + "value": 18.0 + }, + { + "date": "2023-09-20", + "value": 34.4 + }, + { + "date": "2024-03-15", + "value": 4.9 + }, + { + "date": "2024-03-28", + "value": 14.8 + }, + { + "date": "2024-09-05", + "value": 23.0 + }, + { + "date": "2024-09-15", + "value": 9.8 + }, + { + "date": "2024-09-25", + "value": 1.6 + }, + { + "date": "2025-03-10", + "value": 12.3 + }, + { + "date": "2025-03-22", + "value": 4.1 + }, + { + "date": "2025-07-08", + "value": 16.4 + }, + { + "date": "2025-07-22", + "value": 3.3 + }, + { + "date": "2025-09-05", + "value": 11.5 + }, + { + "date": "2025-09-11", + "value": 12.3 + }, + { + "date": "2025-09-17", + "value": 8.2 + }, + { + "date": "2025-09-23", + "value": 9.0 + }, + { + "date": "2025-09-29", + "value": 9.8 + }, + { + "date": "2025-10-06", + "value": 11.5 + }, + { + "date": "2025-10-12", + "value": 6.6 + }, + { + "date": "2025-10-18", + "value": 8.2 + }, + { + "date": "2025-10-24", + "value": 9.0 + }, + { + "date": "2025-10-30", + "value": 9.0 + }, + { + "date": "2025-11-04", + "value": 8.2 + }, + { + "date": "2025-11-10", + "value": 9.8 + }, + { + "date": "2025-11-16", + "value": 9.8 + }, + { + "date": "2025-11-22", + "value": 10.7 + }, + { + "date": "2025-11-28", + "value": 11.5 + }, + { + "date": "2025-12-05", + "value": 8.2 + }, + { + "date": "2025-12-11", + "value": 9.0 + }, + { + "date": "2025-12-17", + "value": 9.8 + }, + { + "date": "2025-12-23", + "value": 10.7 + }, + { + "date": "2025-12-29", + "value": 11.5 + }, + { + "date": "2026-01-06", + "value": 10.7 + }, + { + "date": "2026-01-12", + "value": 11.5 + }, + { + "date": "2026-01-18", + "value": 12.3 + }, + { + "date": "2026-01-24", + "value": 13.1 + }, + { + "date": "2026-01-30", + "value": 9.0 + }, + { + "date": "2026-02-04", + "value": 10.7 + }, + { + "date": "2026-02-10", + "value": 11.5 + }, + { + "date": "2026-02-16", + "value": 12.3 + }, + { + "date": "2026-02-22", + "value": 8.2 + }, + { + "date": "2026-02-28", + "value": 9.0 + }, + { + "date": "2026-03-05", + "value": 10.7 + }, + { + "date": "2026-03-11", + "value": 11.5 + }, + { + "date": "2026-03-17", + "value": 6.6 + }, + { + "date": "2026-03-23", + "value": 8.2 + }, + { + "date": "2026-03-29", + "value": 9.0 + }, + { + "date": "2026-04-06", + "value": 13.1 + }, + { + "date": "2026-04-12", + "value": 8.2 + }, + { + "date": "2026-04-18", + "value": 9.8 + }, + { + "date": "2026-04-24", + "value": 9.8 + }, + { + "date": "2026-04-30", + "value": 10.7 + }, + { + "date": "2026-05-04", + "value": 7.4 + }, + { + "date": "2026-05-10", + "value": 8.2 + }, + { + "date": "2026-05-16", + "value": 9.0 + }, + { + "date": "2026-05-22", + "value": 9.8 + }, + { + "date": "2026-05-28", + "value": 10.7 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 12.3, + "median": 12.3, + "p10": 7.7, + "p25": 9.4, + "p75": 15.2, + "p90": 16.9, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 9.8, + "median": 9.8, + "p10": 5.9, + "p25": 7.4, + "p75": 12.3, + "p90": 13.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 11.5, + "median": 9.8, + "p10": 3.3, + "p25": 5.7, + "p75": 16.4, + "p90": 20.3, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 8.2, + "median": 8.2, + "p10": 4.9, + "p25": 6.1, + "p75": 10.2, + "p90": 11.5, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 9.8, + "median": 9.8, + "p10": 4.6, + "p25": 6.6, + "p75": 13.1, + "p90": 15.1, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 10.2, + "median": 9.8, + "p10": 8.5, + "p25": 9.0, + "p75": 11.5, + "p90": 12.0, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 8.9, + "median": 9.0, + "p10": 7.2, + "p25": 8.2, + "p75": 9.0, + "p90": 10.5, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 10.0, + "median": 9.8, + "p10": 8.9, + "p25": 9.8, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 9.8, + "median": 9.8, + "p10": 8.5, + "p25": 9.0, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 11.3, + "median": 11.5, + "p10": 9.7, + "p25": 10.7, + "p75": 12.3, + "p90": 12.8, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 10.3, + "median": 10.7, + "p10": 8.5, + "p25": 9.0, + "p75": 11.5, + "p90": 12.0, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 9.2, + "median": 9.0, + "p10": 7.2, + "p25": 8.2, + "p75": 10.7, + "p90": 11.2, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 10.3, + "median": 9.8, + "p10": 8.9, + "p25": 9.8, + "p75": 10.7, + "p90": 12.1, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 9.0, + "median": 9.0, + "p10": 7.7, + "p25": 8.2, + "p75": 9.8, + "p90": 10.3, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 17.1, + "median": 17.2, + "std": 3.8, + "min": 9.8, + "max": 31.2, + "p25": 15.2, + "p75": 18.9, + "p85": 20.4, + "p95": 21.8 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 14.8 + }, + { + "date": "2023-10-12", + "value": 20.5 + }, + { + "date": "2024-04-08", + "value": 9.8 + }, + { + "date": "2024-09-20", + "value": 31.2 + }, + { + "date": "2024-10-15", + "value": 16.4 + }, + { + "date": "2025-03-25", + "value": 12.3 + }, + { + "date": "2025-04-10", + "value": 23.0 + }, + { + "date": "2025-07-30", + "value": 19.7 + }, + { + "date": "2025-09-04", + "value": 13.9 + }, + { + "date": "2025-09-10", + "value": 15.6 + }, + { + "date": "2025-09-16", + "value": 17.2 + }, + { + "date": "2025-10-05", + "value": 13.9 + }, + { + "date": "2025-10-11", + "value": 15.6 + }, + { + "date": "2025-10-17", + "value": 16.4 + }, + { + "date": "2025-11-06", + "value": 18.0 + }, + { + "date": "2025-11-12", + "value": 18.9 + }, + { + "date": "2025-11-18", + "value": 20.5 + }, + { + "date": "2025-12-04", + "value": 17.2 + }, + { + "date": "2025-12-10", + "value": 18.9 + }, + { + "date": "2025-12-16", + "value": 20.5 + }, + { + "date": "2026-01-05", + "value": 17.2 + }, + { + "date": "2026-01-11", + "value": 18.9 + }, + { + "date": "2026-01-17", + "value": 11.5 + }, + { + "date": "2026-02-06", + "value": 21.3 + }, + { + "date": "2026-02-12", + "value": 13.9 + }, + { + "date": "2026-02-18", + "value": 15.6 + }, + { + "date": "2026-03-04", + "value": 12.3 + }, + { + "date": "2026-03-10", + "value": 13.9 + }, + { + "date": "2026-03-16", + "value": 15.6 + }, + { + "date": "2026-04-05", + "value": 16.4 + }, + { + "date": "2026-04-11", + "value": 18.0 + }, + { + "date": "2026-04-17", + "value": 18.9 + }, + { + "date": "2026-05-06", + "value": 16.4 + }, + { + "date": "2026-05-12", + "value": 17.2 + }, + { + "date": "2026-05-18", + "value": 18.9 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 14.8, + "median": 14.8, + "p10": 14.8, + "p25": 14.8, + "p75": 14.8, + "p90": 14.8, + "n": 1 + }, + { + "month": "2023-10", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 9.8, + "median": 9.8, + "p10": 9.8, + "p25": 9.8, + "p75": 9.8, + "p90": 9.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-10", + "mean": 16.4, + "median": 16.4, + "p10": 16.4, + "p25": 16.4, + "p75": 16.4, + "p90": 16.4, + "n": 1 + }, + { + "month": "2025-03", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2025-04", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 19.7, + "median": 19.7, + "p10": 19.7, + "p25": 19.7, + "p75": 19.7, + "p90": 19.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 15.6, + "median": 15.6, + "p10": 14.3, + "p25": 14.8, + "p75": 16.4, + "p90": 16.9, + "n": 3 + }, + { + "month": "2025-10", + "mean": 15.3, + "median": 15.6, + "p10": 14.3, + "p25": 14.8, + "p75": 16.0, + "p90": 16.2, + "n": 3 + }, + { + "month": "2025-11", + "mean": 19.1, + "median": 18.9, + "p10": 18.2, + "p25": 18.4, + "p75": 19.7, + "p90": 20.2, + "n": 3 + }, + { + "month": "2025-12", + "mean": 18.9, + "median": 18.9, + "p10": 17.5, + "p25": 18.0, + "p75": 19.7, + "p90": 20.2, + "n": 3 + }, + { + "month": "2026-01", + "mean": 15.8, + "median": 17.2, + "p10": 12.6, + "p25": 14.3, + "p75": 18.0, + "p90": 18.5, + "n": 3 + }, + { + "month": "2026-02", + "mean": 17.0, + "median": 15.6, + "p10": 14.3, + "p25": 14.8, + "p75": 18.4, + "p90": 20.2, + "n": 3 + }, + { + "month": "2026-03", + "mean": 13.9, + "median": 13.9, + "p10": 12.6, + "p25": 13.1, + "p75": 14.8, + "p90": 15.3, + "n": 3 + }, + { + "month": "2026-04", + "mean": 17.8, + "median": 18.0, + "p10": 16.7, + "p25": 17.2, + "p75": 18.4, + "p90": 18.7, + "n": 3 + }, + { + "month": "2026-05", + "mean": 17.5, + "median": 17.2, + "p10": 16.6, + "p25": 16.8, + "p75": 18.0, + "p90": 18.5, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 25.7, + "median": 25.0, + "std": 5.8, + "min": 12.3, + "max": 45.1, + "p25": 22.1, + "p75": 29.5, + "p85": 31.2, + "p95": 34.4 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 23.0 + }, + { + "date": "2022-11-30", + "value": 28.7 + }, + { + "date": "2023-03-15", + "value": 18.0 + }, + { + "date": "2023-07-10", + "value": 34.4 + }, + { + "date": "2023-10-25", + "value": 24.6 + }, + { + "date": "2024-02-08", + "value": 45.1 + }, + { + "date": "2024-05-20", + "value": 20.5 + }, + { + "date": "2024-08-12", + "value": 31.2 + }, + { + "date": "2024-11-05", + "value": 12.3 + }, + { + "date": "2025-01-22", + "value": 26.2 + }, + { + "date": "2025-04-10", + "value": 23.0 + }, + { + "date": "2025-06-18", + "value": 36.9 + }, + { + "date": "2025-07-15", + "value": 24.6 + }, + { + "date": "2025-08-05", + "value": 18.0 + }, + { + "date": "2025-09-05", + "value": 29.5 + }, + { + "date": "2025-09-10", + "value": 31.2 + }, + { + "date": "2025-09-11", + "value": 32.0 + }, + { + "date": "2025-09-17", + "value": 21.3 + }, + { + "date": "2025-10-06", + "value": 29.5 + }, + { + "date": "2025-10-12", + "value": 18.9 + }, + { + "date": "2025-10-18", + "value": 21.3 + }, + { + "date": "2025-11-04", + "value": 22.1 + }, + { + "date": "2025-11-10", + "value": 25.4 + }, + { + "date": "2025-11-16", + "value": 27.1 + }, + { + "date": "2025-12-05", + "value": 22.1 + }, + { + "date": "2025-12-11", + "value": 23.8 + }, + { + "date": "2025-12-17", + "value": 26.2 + }, + { + "date": "2026-01-06", + "value": 21.3 + }, + { + "date": "2026-01-12", + "value": 23.8 + }, + { + "date": "2026-01-18", + "value": 25.4 + }, + { + "date": "2026-02-04", + "value": 27.1 + }, + { + "date": "2026-02-10", + "value": 29.5 + }, + { + "date": "2026-02-16", + "value": 32.0 + }, + { + "date": "2026-03-05", + "value": 27.1 + }, + { + "date": "2026-03-11", + "value": 29.5 + }, + { + "date": "2026-03-17", + "value": 18.9 + }, + { + "date": "2026-04-06", + "value": 32.8 + }, + { + "date": "2026-04-12", + "value": 22.1 + }, + { + "date": "2026-04-18", + "value": 25.4 + }, + { + "date": "2026-05-04", + "value": 19.7 + }, + { + "date": "2026-05-10", + "value": 22.1 + }, + { + "date": "2026-05-16", + "value": 23.8 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 28.7, + "median": 28.7, + "p10": 28.7, + "p25": 28.7, + "p75": 28.7, + "p90": 28.7, + "n": 1 + }, + { + "month": "2023-03", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1 + }, + { + "month": "2023-10", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2024-02", + "mean": 45.1, + "median": 45.1, + "p10": 45.1, + "p25": 45.1, + "p75": 45.1, + "p90": 45.1, + "n": 1 + }, + { + "month": "2024-05", + "mean": 20.5, + "median": 20.5, + "p10": 20.5, + "p25": 20.5, + "p75": 20.5, + "p90": 20.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 31.2, + "median": 31.2, + "p10": 31.2, + "p25": 31.2, + "p75": 31.2, + "p90": 31.2, + "n": 1 + }, + { + "month": "2024-11", + "mean": 12.3, + "median": 12.3, + "p10": 12.3, + "p25": 12.3, + "p75": 12.3, + "p90": 12.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 26.2, + "median": 26.2, + "p10": 26.2, + "p25": 26.2, + "p75": 26.2, + "p90": 26.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 23.0, + "median": 23.0, + "p10": 23.0, + "p25": 23.0, + "p75": 23.0, + "p90": 23.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 36.9, + "median": 36.9, + "p10": 36.9, + "p25": 36.9, + "p75": 36.9, + "p90": 36.9, + "n": 1 + }, + { + "month": "2025-07", + "mean": 24.6, + "median": 24.6, + "p10": 24.6, + "p25": 24.6, + "p75": 24.6, + "p90": 24.6, + "n": 1 + }, + { + "month": "2025-08", + "mean": 18.0, + "median": 18.0, + "p10": 18.0, + "p25": 18.0, + "p75": 18.0, + "p90": 18.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 28.5, + "median": 30.3, + "p10": 23.8, + "p25": 27.5, + "p75": 31.4, + "p90": 31.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 23.2, + "median": 21.3, + "p10": 19.4, + "p25": 20.1, + "p75": 25.4, + "p90": 27.9, + "n": 3 + }, + { + "month": "2025-11", + "mean": 24.8, + "median": 25.4, + "p10": 22.8, + "p25": 23.8, + "p75": 26.2, + "p90": 26.7, + "n": 3 + }, + { + "month": "2025-12", + "mean": 24.0, + "median": 23.8, + "p10": 22.5, + "p25": 23.0, + "p75": 25.0, + "p90": 25.7, + "n": 3 + }, + { + "month": "2026-01", + "mean": 23.5, + "median": 23.8, + "p10": 21.8, + "p25": 22.5, + "p75": 24.6, + "p90": 25.1, + "n": 3 + }, + { + "month": "2026-02", + "mean": 29.5, + "median": 29.5, + "p10": 27.6, + "p25": 28.3, + "p75": 30.7, + "p90": 31.5, + "n": 3 + }, + { + "month": "2026-03", + "mean": 25.2, + "median": 27.1, + "p10": 20.5, + "p25": 23.0, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-04", + "mean": 26.8, + "median": 25.4, + "p10": 22.8, + "p25": 23.8, + "p75": 29.1, + "p90": 31.3, + "n": 3 + }, + { + "month": "2026-05", + "mean": 21.9, + "median": 22.1, + "p10": 20.2, + "p25": 20.9, + "p75": 23.0, + "p90": 23.5, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 36.9, + "median": 36.1, + "std": 11.5, + "min": 8.2, + "max": 77.9, + "p25": 29.5, + "p75": 40.2, + "p85": 43.5, + "p95": 55.4 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 23.37, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 34.4 + }, + { + "date": "2023-05-05", + "value": 53.3 + }, + { + "date": "2023-05-20", + "value": 23.0 + }, + { + "date": "2024-01-10", + "value": 77.9 + }, + { + "date": "2024-01-25", + "value": 28.7 + }, + { + "date": "2024-08-15", + "value": 8.2 + }, + { + "date": "2025-02-05", + "value": 64.0 + }, + { + "date": "2025-02-18", + "value": 45.1 + }, + { + "date": "2025-08-10", + "value": 34.4 + }, + { + "date": "2025-08-20", + "value": 26.2 + }, + { + "date": "2025-09-06", + "value": 32.0 + }, + { + "date": "2025-09-12", + "value": 34.4 + }, + { + "date": "2025-09-18", + "value": 37.7 + }, + { + "date": "2025-10-04", + "value": 40.2 + }, + { + "date": "2025-10-10", + "value": 43.5 + }, + { + "date": "2025-10-16", + "value": 46.7 + }, + { + "date": "2025-11-05", + "value": 39.4 + }, + { + "date": "2025-11-11", + "value": 42.6 + }, + { + "date": "2025-11-17", + "value": 27.9 + }, + { + "date": "2025-12-06", + "value": 39.4 + }, + { + "date": "2025-12-12", + "value": 24.6 + }, + { + "date": "2025-12-18", + "value": 27.9 + }, + { + "date": "2026-01-04", + "value": 29.5 + }, + { + "date": "2026-01-10", + "value": 33.6 + }, + { + "date": "2026-01-16", + "value": 35.3 + }, + { + "date": "2026-02-05", + "value": 29.5 + }, + { + "date": "2026-02-11", + "value": 32.0 + }, + { + "date": "2026-02-17", + "value": 34.4 + }, + { + "date": "2026-03-06", + "value": 37.7 + }, + { + "date": "2026-03-12", + "value": 40.2 + }, + { + "date": "2026-03-18", + "value": 43.5 + }, + { + "date": "2026-04-04", + "value": 36.9 + }, + { + "date": "2026-04-10", + "value": 39.4 + }, + { + "date": "2026-04-16", + "value": 42.6 + }, + { + "date": "2026-05-05", + "value": 36.1 + }, + { + "date": "2026-05-11", + "value": 39.4 + }, + { + "date": "2026-05-17", + "value": 24.6 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 34.4, + "median": 34.4, + "p10": 34.4, + "p25": 34.4, + "p75": 34.4, + "p90": 34.4, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 38.1, + "median": 38.1, + "p10": 26.0, + "p25": 30.6, + "p75": 45.8, + "p90": 50.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 53.3, + "median": 53.3, + "p10": 33.6, + "p25": 41.0, + "p75": 65.6, + "p90": 73.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 8.2, + "median": 8.2, + "p10": 8.2, + "p25": 8.2, + "p75": 8.2, + "p90": 8.2, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 54.5, + "median": 54.5, + "p10": 47.0, + "p25": 49.9, + "p75": 59.3, + "p90": 62.1, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 30.3, + "median": 30.3, + "p10": 27.1, + "p25": 28.3, + "p75": 32.4, + "p90": 33.6, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 34.7, + "median": 34.4, + "p10": 32.5, + "p25": 33.2, + "p75": 36.1, + "p90": 37.1, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 43.5, + "median": 43.5, + "p10": 40.8, + "p25": 41.8, + "p75": 45.1, + "p90": 46.1, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 36.7, + "median": 39.4, + "p10": 30.2, + "p25": 33.6, + "p75": 41.0, + "p90": 42.0, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 30.6, + "median": 27.9, + "p10": 25.3, + "p25": 26.2, + "p75": 33.6, + "p90": 37.1, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 32.8, + "median": 33.6, + "p10": 30.3, + "p25": 31.6, + "p75": 34.4, + "p90": 34.9, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 32.0, + "median": 32.0, + "p10": 30.0, + "p25": 30.7, + "p75": 33.2, + "p90": 33.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 40.4, + "median": 40.2, + "p10": 38.2, + "p25": 38.9, + "p75": 41.8, + "p90": 42.8, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 39.6, + "median": 39.4, + "p10": 37.4, + "p25": 38.1, + "p75": 41.0, + "p90": 42.0, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 33.4, + "median": 36.1, + "p10": 26.9, + "p25": 30.3, + "p75": 37.7, + "p90": 38.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ] + }, + { + "id": "meadow-espresso", + "name": "Meadow Espresso", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 54.3, + "median": 54.0, + "std": 18.0, + "min": 10.8, + "max": 141.8, + "p25": 47.2, + "p75": 60.8, + "p85": 64.8, + "p95": 75.3 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 74.2 + }, + { + "date": "2022-06-10", + "value": 56.7 + }, + { + "date": "2022-09-22", + "value": 10.8 + }, + { + "date": "2022-12-05", + "value": 85.1 + }, + { + "date": "2023-02-14", + "value": 51.3 + }, + { + "date": "2023-05-30", + "value": 29.7 + }, + { + "date": "2023-08-17", + "value": 95.9 + }, + { + "date": "2023-11-02", + "value": 40.5 + }, + { + "date": "2024-01-25", + "value": 60.8 + }, + { + "date": "2024-04-11", + "value": 24.3 + }, + { + "date": "2024-07-09", + "value": 141.8 + }, + { + "date": "2024-10-03", + "value": 47.2 + }, + { + "date": "2025-01-20", + "value": 16.2 + }, + { + "date": "2025-04-08", + "value": 64.8 + }, + { + "date": "2025-09-05", + "value": 52.7 + }, + { + "date": "2025-09-11", + "value": 55.4 + }, + { + "date": "2025-09-17", + "value": 59.4 + }, + { + "date": "2025-09-23", + "value": 64.8 + }, + { + "date": "2025-09-29", + "value": 68.9 + }, + { + "date": "2025-10-06", + "value": 50.0 + }, + { + "date": "2025-10-12", + "value": 54.0 + }, + { + "date": "2025-10-18", + "value": 59.4 + }, + { + "date": "2025-10-24", + "value": 63.5 + }, + { + "date": "2025-10-30", + "value": 41.9 + }, + { + "date": "2025-11-04", + "value": 48.6 + }, + { + "date": "2025-11-10", + "value": 54.0 + }, + { + "date": "2025-11-16", + "value": 58.1 + }, + { + "date": "2025-11-22", + "value": 36.5 + }, + { + "date": "2025-11-28", + "value": 41.9 + }, + { + "date": "2025-12-05", + "value": 62.1 + }, + { + "date": "2025-12-11", + "value": 66.2 + }, + { + "date": "2025-12-17", + "value": 44.6 + }, + { + "date": "2025-12-23", + "value": 50.0 + }, + { + "date": "2025-12-29", + "value": 52.7 + }, + { + "date": "2026-01-06", + "value": 60.8 + }, + { + "date": "2026-01-12", + "value": 39.2 + }, + { + "date": "2026-01-18", + "value": 44.6 + }, + { + "date": "2026-01-24", + "value": 47.2 + }, + { + "date": "2026-01-30", + "value": 51.3 + }, + { + "date": "2026-02-04", + "value": 47.2 + }, + { + "date": "2026-02-10", + "value": 52.7 + }, + { + "date": "2026-02-16", + "value": 55.4 + }, + { + "date": "2026-02-22", + "value": 59.4 + }, + { + "date": "2026-02-28", + "value": 64.8 + }, + { + "date": "2026-03-05", + "value": 47.2 + }, + { + "date": "2026-03-11", + "value": 50.0 + }, + { + "date": "2026-03-17", + "value": 54.0 + }, + { + "date": "2026-03-23", + "value": 59.4 + }, + { + "date": "2026-03-29", + "value": 63.5 + }, + { + "date": "2026-04-06", + "value": 44.6 + }, + { + "date": "2026-04-12", + "value": 48.6 + }, + { + "date": "2026-04-18", + "value": 54.0 + }, + { + "date": "2026-04-24", + "value": 58.1 + }, + { + "date": "2026-04-30", + "value": 36.5 + }, + { + "date": "2026-05-04", + "value": 56.7 + }, + { + "date": "2026-05-10", + "value": 62.1 + }, + { + "date": "2026-05-16", + "value": 66.2 + }, + { + "date": "2026-05-22", + "value": 44.6 + }, + { + "date": "2026-05-28", + "value": 50.0 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2022-06", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1 + }, + { + "month": "2022-09", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2022-12", + "mean": 85.1, + "median": 85.1, + "p10": 85.1, + "p25": 85.1, + "p75": 85.1, + "p90": 85.1, + "n": 1 + }, + { + "month": "2023-02", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2023-05", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2023-08", + "mean": 95.9, + "median": 95.9, + "p10": 95.9, + "p25": 95.9, + "p75": 95.9, + "p90": 95.9, + "n": 1 + }, + { + "month": "2023-11", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 60.8, + "median": 60.8, + "p10": 60.8, + "p25": 60.8, + "p75": 60.8, + "p90": 60.8, + "n": 1 + }, + { + "month": "2024-04", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2024-07", + "mean": 141.8, + "median": 141.8, + "p10": 141.8, + "p25": 141.8, + "p75": 141.8, + "p90": 141.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2025-09", + "mean": 60.2, + "median": 59.4, + "p10": 53.7, + "p25": 55.4, + "p75": 64.8, + "p90": 67.2, + "n": 5 + }, + { + "month": "2025-10", + "mean": 53.7, + "median": 54.0, + "p10": 45.1, + "p25": 50.0, + "p75": 59.4, + "p90": 61.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 47.8, + "median": 48.6, + "p10": 38.6, + "p25": 41.9, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2025-12", + "mean": 55.1, + "median": 52.7, + "p10": 46.7, + "p25": 50.0, + "p75": 62.1, + "p90": 64.5, + "n": 5 + }, + { + "month": "2026-01", + "mean": 48.6, + "median": 47.2, + "p10": 41.3, + "p25": 44.6, + "p75": 51.3, + "p90": 57.0, + "n": 5 + }, + { + "month": "2026-02", + "mean": 55.9, + "median": 55.4, + "p10": 49.4, + "p25": 52.7, + "p75": 59.4, + "p90": 62.6, + "n": 5 + }, + { + "month": "2026-03", + "mean": 54.8, + "median": 54.0, + "p10": 48.3, + "p25": 50.0, + "p75": 59.4, + "p90": 61.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 48.3, + "median": 48.6, + "p10": 39.7, + "p25": 44.6, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-05", + "mean": 55.9, + "median": 56.7, + "p10": 46.7, + "p25": 50.0, + "p75": 62.1, + "p90": 64.5, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 45.1, + "median": 44.6, + "std": 15.4, + "min": 6.8, + "max": 110.7, + "p25": 37.8, + "p75": 51.3, + "p85": 54.9, + "p95": 69.7 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 43.2 + }, + { + "date": "2022-04-19", + "value": 64.8 + }, + { + "date": "2022-07-11", + "value": 6.8 + }, + { + "date": "2022-09-28", + "value": 90.5 + }, + { + "date": "2022-12-15", + "value": 33.8 + }, + { + "date": "2023-03-07", + "value": 55.4 + }, + { + "date": "2023-05-22", + "value": 20.2 + }, + { + "date": "2023-08-09", + "value": 110.7 + }, + { + "date": "2023-10-30", + "value": 51.3 + }, + { + "date": "2024-01-16", + "value": 27.0 + }, + { + "date": "2024-03-25", + "value": 70.2 + }, + { + "date": "2024-06-12", + "value": 13.5 + }, + { + "date": "2024-08-28", + "value": 59.4 + }, + { + "date": "2024-11-14", + "value": 37.8 + }, + { + "date": "2025-01-06", + "value": 47.2 + }, + { + "date": "2025-03-18", + "value": 24.3 + }, + { + "date": "2025-05-29", + "value": 74.2 + }, + { + "date": "2025-08-12", + "value": 35.1 + }, + { + "date": "2025-09-04", + "value": 35.1 + }, + { + "date": "2025-09-10", + "value": 39.2 + }, + { + "date": "2025-09-16", + "value": 41.9 + }, + { + "date": "2025-09-22", + "value": 45.9 + }, + { + "date": "2025-09-28", + "value": 50.0 + }, + { + "date": "2025-10-05", + "value": 35.1 + }, + { + "date": "2025-10-11", + "value": 37.8 + }, + { + "date": "2025-10-17", + "value": 41.9 + }, + { + "date": "2025-10-23", + "value": 44.6 + }, + { + "date": "2025-10-29", + "value": 48.6 + }, + { + "date": "2025-11-06", + "value": 44.6 + }, + { + "date": "2025-11-12", + "value": 48.6 + }, + { + "date": "2025-11-18", + "value": 51.3 + }, + { + "date": "2025-11-24", + "value": 56.7 + }, + { + "date": "2025-11-30", + "value": 37.8 + }, + { + "date": "2025-12-04", + "value": 43.2 + }, + { + "date": "2025-12-10", + "value": 47.2 + }, + { + "date": "2025-12-16", + "value": 51.3 + }, + { + "date": "2025-12-22", + "value": 32.4 + }, + { + "date": "2025-12-28", + "value": 37.8 + }, + { + "date": "2026-01-05", + "value": 54.0 + }, + { + "date": "2026-01-11", + "value": 58.1 + }, + { + "date": "2026-01-17", + "value": 39.2 + }, + { + "date": "2026-01-23", + "value": 44.6 + }, + { + "date": "2026-01-29", + "value": 47.2 + }, + { + "date": "2026-02-06", + "value": 54.0 + }, + { + "date": "2026-02-12", + "value": 35.1 + }, + { + "date": "2026-02-18", + "value": 39.2 + }, + { + "date": "2026-02-24", + "value": 41.9 + }, + { + "date": "2026-02-30", + "value": 45.9 + }, + { + "date": "2026-03-04", + "value": 29.7 + }, + { + "date": "2026-03-10", + "value": 35.1 + }, + { + "date": "2026-03-16", + "value": 37.8 + }, + { + "date": "2026-03-22", + "value": 41.9 + }, + { + "date": "2026-03-28", + "value": 44.6 + }, + { + "date": "2026-04-05", + "value": 41.9 + }, + { + "date": "2026-04-11", + "value": 44.6 + }, + { + "date": "2026-04-17", + "value": 48.6 + }, + { + "date": "2026-04-23", + "value": 51.3 + }, + { + "date": "2026-04-29", + "value": 56.7 + }, + { + "date": "2026-05-06", + "value": 40.5 + }, + { + "date": "2026-05-12", + "value": 43.2 + }, + { + "date": "2026-05-18", + "value": 47.2 + }, + { + "date": "2026-05-24", + "value": 51.3 + }, + { + "date": "2026-05-30", + "value": 32.4 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 43.2, + "median": 43.2, + "p10": 43.2, + "p25": 43.2, + "p75": 43.2, + "p90": 43.2, + "n": 1 + }, + { + "month": "2022-04", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2022-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-09", + "mean": 90.5, + "median": 90.5, + "p10": 90.5, + "p25": 90.5, + "p75": 90.5, + "p90": 90.5, + "n": 1 + }, + { + "month": "2022-12", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2023-03", + "mean": 55.4, + "median": 55.4, + "p10": 55.4, + "p25": 55.4, + "p75": 55.4, + "p90": 55.4, + "n": 1 + }, + { + "month": "2023-05", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2023-08", + "mean": 110.7, + "median": 110.7, + "p10": 110.7, + "p25": 110.7, + "p75": 110.7, + "p90": 110.7, + "n": 1 + }, + { + "month": "2023-10", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-01", + "mean": 27.0, + "median": 27.0, + "p10": 27.0, + "p25": 27.0, + "p75": 27.0, + "p90": 27.0, + "n": 1 + }, + { + "month": "2024-03", + "mean": 70.2, + "median": 70.2, + "p10": 70.2, + "p25": 70.2, + "p75": 70.2, + "p90": 70.2, + "n": 1 + }, + { + "month": "2024-06", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 59.4, + "median": 59.4, + "p10": 59.4, + "p25": 59.4, + "p75": 59.4, + "p90": 59.4, + "n": 1 + }, + { + "month": "2024-11", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-01", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2025-03", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2025-05", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 35.1, + "median": 35.1, + "p10": 35.1, + "p25": 35.1, + "p75": 35.1, + "p90": 35.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 42.4, + "median": 41.9, + "p10": 36.7, + "p25": 39.2, + "p75": 45.9, + "p90": 48.3, + "n": 5 + }, + { + "month": "2025-10", + "mean": 41.6, + "median": 41.9, + "p10": 36.2, + "p25": 37.8, + "p75": 44.6, + "p90": 47.0, + "n": 5 + }, + { + "month": "2025-11", + "mean": 47.8, + "median": 48.6, + "p10": 40.5, + "p25": 44.6, + "p75": 51.3, + "p90": 54.5, + "n": 5 + }, + { + "month": "2025-12", + "mean": 42.4, + "median": 43.2, + "p10": 34.6, + "p25": 37.8, + "p75": 47.2, + "p90": 49.7, + "n": 5 + }, + { + "month": "2026-01", + "mean": 48.6, + "median": 47.2, + "p10": 41.3, + "p25": 44.6, + "p75": 54.0, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-02", + "mean": 43.2, + "median": 41.9, + "p10": 36.7, + "p25": 39.2, + "p75": 45.9, + "p90": 50.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 37.8, + "median": 37.8, + "p10": 31.9, + "p25": 35.1, + "p75": 41.9, + "p90": 43.5, + "n": 5 + }, + { + "month": "2026-04", + "mean": 48.6, + "median": 48.6, + "p10": 42.9, + "p25": 44.6, + "p75": 51.3, + "p90": 54.5, + "n": 5 + }, + { + "month": "2026-05", + "mean": 42.9, + "median": 43.2, + "p10": 35.6, + "p25": 40.5, + "p75": 47.2, + "p90": 49.7, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 35.2, + "median": 33.8, + "std": 10.8, + "min": 9.5, + "max": 83.7, + "p25": 30.4, + "p75": 39.2, + "p85": 40.5, + "p95": 49.3 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 47.2 + }, + { + "date": "2022-10-18", + "value": 21.6 + }, + { + "date": "2023-01-24", + "value": 83.7 + }, + { + "date": "2023-06-15", + "value": 9.5 + }, + { + "date": "2023-09-28", + "value": 54.0 + }, + { + "date": "2024-02-12", + "value": 33.8 + }, + { + "date": "2024-05-07", + "value": 64.8 + }, + { + "date": "2024-09-19", + "value": 16.2 + }, + { + "date": "2025-02-04", + "value": 40.5 + }, + { + "date": "2025-06-10", + "value": 18.9 + }, + { + "date": "2025-09-06", + "value": 40.5 + }, + { + "date": "2025-09-12", + "value": 25.7 + }, + { + "date": "2025-09-18", + "value": 29.7 + }, + { + "date": "2025-09-24", + "value": 31.1 + }, + { + "date": "2025-09-30", + "value": 33.8 + }, + { + "date": "2025-10-04", + "value": 31.1 + }, + { + "date": "2025-10-10", + "value": 33.8 + }, + { + "date": "2025-10-16", + "value": 36.5 + }, + { + "date": "2025-10-22", + "value": 39.2 + }, + { + "date": "2025-10-28", + "value": 41.9 + }, + { + "date": "2025-11-05", + "value": 31.1 + }, + { + "date": "2025-11-11", + "value": 33.8 + }, + { + "date": "2025-11-17", + "value": 36.5 + }, + { + "date": "2025-11-23", + "value": 39.2 + }, + { + "date": "2025-11-29", + "value": 41.9 + }, + { + "date": "2025-12-06", + "value": 29.7 + }, + { + "date": "2025-12-12", + "value": 32.4 + }, + { + "date": "2025-12-18", + "value": 35.1 + }, + { + "date": "2025-12-24", + "value": 37.8 + }, + { + "date": "2025-12-30", + "value": 24.3 + }, + { + "date": "2026-01-04", + "value": 37.8 + }, + { + "date": "2026-01-10", + "value": 40.5 + }, + { + "date": "2026-01-16", + "value": 43.2 + }, + { + "date": "2026-01-22", + "value": 29.7 + }, + { + "date": "2026-01-28", + "value": 32.4 + }, + { + "date": "2026-02-05", + "value": 36.5 + }, + { + "date": "2026-02-11", + "value": 40.5 + }, + { + "date": "2026-02-17", + "value": 25.7 + }, + { + "date": "2026-02-23", + "value": 29.7 + }, + { + "date": "2026-02-29", + "value": 31.1 + }, + { + "date": "2026-03-06", + "value": 45.9 + }, + { + "date": "2026-03-12", + "value": 31.1 + }, + { + "date": "2026-03-18", + "value": 33.8 + }, + { + "date": "2026-03-24", + "value": 36.5 + }, + { + "date": "2026-03-30", + "value": 39.2 + }, + { + "date": "2026-04-04", + "value": 27.0 + }, + { + "date": "2026-04-10", + "value": 31.1 + }, + { + "date": "2026-04-16", + "value": 33.8 + }, + { + "date": "2026-04-22", + "value": 36.5 + }, + { + "date": "2026-04-28", + "value": 39.2 + }, + { + "date": "2026-05-05", + "value": 27.0 + }, + { + "date": "2026-05-11", + "value": 29.7 + }, + { + "date": "2026-05-17", + "value": 32.4 + }, + { + "date": "2026-05-23", + "value": 35.1 + }, + { + "date": "2026-05-29", + "value": 37.8 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 21.6, + "median": 21.6, + "p10": 21.6, + "p25": 21.6, + "p75": 21.6, + "p90": 21.6, + "n": 1 + }, + { + "month": "2023-01", + "mean": 83.7, + "median": 83.7, + "p10": 83.7, + "p25": 83.7, + "p75": 83.7, + "p90": 83.7, + "n": 1 + }, + { + "month": "2023-06", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 54.0, + "median": 54.0, + "p10": 54.0, + "p25": 54.0, + "p75": 54.0, + "p90": 54.0, + "n": 1 + }, + { + "month": "2024-02", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-05", + "mean": 64.8, + "median": 64.8, + "p10": 64.8, + "p25": 64.8, + "p75": 64.8, + "p90": 64.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2025-02", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2025-06", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 32.1, + "median": 31.1, + "p10": 27.3, + "p25": 29.7, + "p75": 33.8, + "p90": 37.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 36.5, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-11", + "mean": 36.5, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 40.8, + "n": 5 + }, + { + "month": "2025-12", + "mean": 31.9, + "median": 32.4, + "p10": 26.5, + "p25": 29.7, + "p75": 35.1, + "p90": 36.7, + "n": 5 + }, + { + "month": "2026-01", + "mean": 36.7, + "median": 37.8, + "p10": 30.8, + "p25": 32.4, + "p75": 40.5, + "p90": 42.1, + "n": 5 + }, + { + "month": "2026-02", + "mean": 32.7, + "median": 31.1, + "p10": 27.3, + "p25": 29.7, + "p75": 36.5, + "p90": 38.9, + "n": 5 + }, + { + "month": "2026-03", + "mean": 37.3, + "median": 36.5, + "p10": 32.1, + "p25": 33.8, + "p75": 39.2, + "p90": 43.2, + "n": 5 + }, + { + "month": "2026-04", + "mean": 33.5, + "median": 33.8, + "p10": 28.6, + "p25": 31.1, + "p75": 36.5, + "p90": 38.1, + "n": 5 + }, + { + "month": "2026-05", + "mean": 32.4, + "median": 32.4, + "p10": 28.1, + "p25": 29.7, + "p75": 35.1, + "p90": 36.7, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 65.2, + "median": 62.1, + "std": 26.7, + "min": 6.8, + "max": 175.5, + "p25": 52.0, + "p75": 73.6, + "p85": 82.4, + "p95": 118.4 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 4.32, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 47.2 + }, + { + "date": "2022-04-15", + "value": 83.7 + }, + { + "date": "2022-04-28", + "value": 24.3 + }, + { + "date": "2022-08-05", + "value": 118.8 + }, + { + "date": "2022-08-12", + "value": 56.7 + }, + { + "date": "2022-08-20", + "value": 74.2 + }, + { + "date": "2022-08-28", + "value": 40.5 + }, + { + "date": "2023-01-10", + "value": 97.2 + }, + { + "date": "2023-01-22", + "value": 33.8 + }, + { + "date": "2023-01-30", + "value": 64.8 + }, + { + "date": "2023-06-05", + "value": 20.2 + }, + { + "date": "2023-06-18", + "value": 128.2 + }, + { + "date": "2023-10-03", + "value": 175.5 + }, + { + "date": "2023-10-10", + "value": 60.8 + }, + { + "date": "2023-10-18", + "value": 51.3 + }, + { + "date": "2023-10-25", + "value": 87.8 + }, + { + "date": "2023-10-30", + "value": 29.7 + }, + { + "date": "2024-03-05", + "value": 105.3 + }, + { + "date": "2024-03-12", + "value": 6.8 + }, + { + "date": "2024-03-20", + "value": 74.2 + }, + { + "date": "2024-03-28", + "value": 54.0 + }, + { + "date": "2024-07-08", + "value": 37.8 + }, + { + "date": "2024-07-15", + "value": 114.8 + }, + { + "date": "2024-07-22", + "value": 67.5 + }, + { + "date": "2024-11-04", + "value": 148.5 + }, + { + "date": "2024-11-11", + "value": 43.2 + }, + { + "date": "2024-11-18", + "value": 91.8 + }, + { + "date": "2024-11-25", + "value": 60.8 + }, + { + "date": "2024-11-30", + "value": 124.2 + }, + { + "date": "2025-03-03", + "value": 27.0 + }, + { + "date": "2025-03-10", + "value": 78.3 + }, + { + "date": "2025-03-17", + "value": 47.2 + }, + { + "date": "2025-03-24", + "value": 56.7 + }, + { + "date": "2025-07-02", + "value": 101.2 + }, + { + "date": "2025-07-09", + "value": 16.2 + }, + { + "date": "2025-07-16", + "value": 64.8 + }, + { + "date": "2025-07-23", + "value": 81.0 + }, + { + "date": "2025-07-30", + "value": 51.3 + }, + { + "date": "2025-09-05", + "value": 66.2 + }, + { + "date": "2025-09-11", + "value": 72.9 + }, + { + "date": "2025-09-17", + "value": 45.9 + }, + { + "date": "2025-09-23", + "value": 52.7 + }, + { + "date": "2025-09-29", + "value": 56.7 + }, + { + "date": "2025-10-06", + "value": 82.4 + }, + { + "date": "2025-10-12", + "value": 55.4 + }, + { + "date": "2025-10-18", + "value": 62.1 + }, + { + "date": "2025-10-24", + "value": 66.2 + }, + { + "date": "2025-10-30", + "value": 71.6 + }, + { + "date": "2025-11-04", + "value": 48.6 + }, + { + "date": "2025-11-10", + "value": 55.4 + }, + { + "date": "2025-11-16", + "value": 59.4 + }, + { + "date": "2025-11-22", + "value": 64.8 + }, + { + "date": "2025-11-28", + "value": 70.2 + }, + { + "date": "2025-12-05", + "value": 48.6 + }, + { + "date": "2025-12-11", + "value": 52.7 + }, + { + "date": "2025-12-17", + "value": 58.1 + }, + { + "date": "2025-12-23", + "value": 63.5 + }, + { + "date": "2025-12-29", + "value": 68.9 + }, + { + "date": "2026-01-06", + "value": 63.5 + }, + { + "date": "2026-01-12", + "value": 67.5 + }, + { + "date": "2026-01-18", + "value": 72.9 + }, + { + "date": "2026-01-24", + "value": 78.3 + }, + { + "date": "2026-01-30", + "value": 52.7 + }, + { + "date": "2026-02-04", + "value": 60.8 + }, + { + "date": "2026-02-10", + "value": 66.2 + }, + { + "date": "2026-02-16", + "value": 72.9 + }, + { + "date": "2026-02-22", + "value": 45.9 + }, + { + "date": "2026-02-28", + "value": 52.7 + }, + { + "date": "2026-03-05", + "value": 75.6 + }, + { + "date": "2026-03-11", + "value": 82.4 + }, + { + "date": "2026-03-17", + "value": 55.4 + }, + { + "date": "2026-03-23", + "value": 62.1 + }, + { + "date": "2026-03-29", + "value": 66.2 + }, + { + "date": "2026-04-06", + "value": 75.6 + }, + { + "date": "2026-04-12", + "value": 48.6 + }, + { + "date": "2026-04-18", + "value": 55.4 + }, + { + "date": "2026-04-24", + "value": 59.4 + }, + { + "date": "2026-04-30", + "value": 64.8 + }, + { + "date": "2026-05-04", + "value": 43.2 + }, + { + "date": "2026-05-10", + "value": 48.6 + }, + { + "date": "2026-05-16", + "value": 52.7 + }, + { + "date": "2026-05-22", + "value": 58.1 + }, + { + "date": "2026-05-28", + "value": 63.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 51.7, + "median": 47.2, + "p10": 28.9, + "p25": 35.8, + "p75": 65.5, + "p90": 76.4, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 72.6, + "median": 65.5, + "p10": 45.4, + "p25": 52.7, + "p75": 85.5, + "p90": 105.4, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 65.2, + "median": 64.8, + "p10": 40.0, + "p25": 49.3, + "p75": 81.0, + "p90": 90.7, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 74.2, + "median": 74.2, + "p10": 31.1, + "p25": 47.2, + "p75": 101.2, + "p90": 117.5, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 81.0, + "median": 60.8, + "p10": 38.3, + "p25": 51.3, + "p75": 87.8, + "p90": 140.4, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 60.1, + "median": 64.1, + "p10": 20.9, + "p25": 42.3, + "p75": 82.1, + "p90": 96.0, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 73.3, + "median": 67.5, + "p10": 43.7, + "p25": 52.7, + "p75": 91.1, + "p90": 105.3, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 93.7, + "median": 91.8, + "p10": 50.2, + "p25": 60.8, + "p75": 124.2, + "p90": 138.8, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 52.4, + "median": 52.0, + "p10": 33.1, + "p25": 42.3, + "p75": 62.1, + "p90": 71.8, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 62.9, + "median": 64.8, + "p10": 30.2, + "p25": 51.3, + "p75": 81.0, + "p90": 93.2, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 58.9, + "median": 56.7, + "p10": 48.6, + "p25": 52.7, + "p75": 66.2, + "p90": 70.2, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 67.5, + "median": 66.2, + "p10": 58.1, + "p25": 62.1, + "p75": 71.6, + "p90": 78.0, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 59.7, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 58.3, + "median": 58.1, + "p10": 50.2, + "p25": 52.7, + "p75": 63.5, + "p90": 66.7, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 67.0, + "median": 67.5, + "p10": 57.0, + "p25": 63.5, + "p75": 72.9, + "p90": 76.1, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 59.7, + "median": 60.8, + "p10": 48.6, + "p25": 52.7, + "p75": 66.2, + "p90": 70.2, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 68.3, + "median": 66.2, + "p10": 58.1, + "p25": 62.1, + "p75": 75.6, + "p90": 79.7, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 60.8, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 64.8, + "p90": 71.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 53.2, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 58.1, + "p90": 61.3, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 49.4, + "median": 45.9, + "std": 21.3, + "min": 4.1, + "max": 132.3, + "p25": 37.8, + "p75": 55.4, + "p85": 60.8, + "p95": 93.4 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 2.43, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 37.8 + }, + { + "date": "2022-05-10", + "value": 60.8 + }, + { + "date": "2022-05-18", + "value": 16.2 + }, + { + "date": "2022-05-25", + "value": 83.7 + }, + { + "date": "2023-02-06", + "value": 44.6 + }, + { + "date": "2023-02-14", + "value": 105.3 + }, + { + "date": "2023-02-22", + "value": 27.0 + }, + { + "date": "2023-02-28", + "value": 74.2 + }, + { + "date": "2023-09-05", + "value": 10.8 + }, + { + "date": "2023-09-15", + "value": 56.7 + }, + { + "date": "2023-09-25", + "value": 87.8 + }, + { + "date": "2024-04-03", + "value": 51.3 + }, + { + "date": "2024-04-10", + "value": 20.2 + }, + { + "date": "2024-04-17", + "value": 97.2 + }, + { + "date": "2024-04-24", + "value": 33.8 + }, + { + "date": "2024-10-02", + "value": 64.8 + }, + { + "date": "2024-10-09", + "value": 4.1 + }, + { + "date": "2024-10-16", + "value": 114.8 + }, + { + "date": "2024-10-23", + "value": 40.5 + }, + { + "date": "2024-10-30", + "value": 74.2 + }, + { + "date": "2025-04-07", + "value": 29.7 + }, + { + "date": "2025-04-14", + "value": 54.0 + }, + { + "date": "2025-04-21", + "value": 132.3 + }, + { + "date": "2025-04-28", + "value": 24.3 + }, + { + "date": "2025-09-04", + "value": 52.7 + }, + { + "date": "2025-09-10", + "value": 55.4 + }, + { + "date": "2025-09-16", + "value": 60.8 + }, + { + "date": "2025-09-22", + "value": 40.5 + }, + { + "date": "2025-09-28", + "value": 45.9 + }, + { + "date": "2025-10-05", + "value": 51.3 + }, + { + "date": "2025-10-11", + "value": 55.4 + }, + { + "date": "2025-10-17", + "value": 36.5 + }, + { + "date": "2025-10-23", + "value": 40.5 + }, + { + "date": "2025-10-29", + "value": 43.2 + }, + { + "date": "2025-11-06", + "value": 51.3 + }, + { + "date": "2025-11-12", + "value": 31.1 + }, + { + "date": "2025-11-18", + "value": 36.5 + }, + { + "date": "2025-11-24", + "value": 39.2 + }, + { + "date": "2025-11-30", + "value": 43.2 + }, + { + "date": "2025-12-04", + "value": 37.8 + }, + { + "date": "2025-12-10", + "value": 43.2 + }, + { + "date": "2025-12-16", + "value": 45.9 + }, + { + "date": "2025-12-22", + "value": 50.0 + }, + { + "date": "2025-12-28", + "value": 54.0 + }, + { + "date": "2026-01-05", + "value": 37.8 + }, + { + "date": "2026-01-11", + "value": 41.9 + }, + { + "date": "2026-01-17", + "value": 44.6 + }, + { + "date": "2026-01-23", + "value": 48.6 + }, + { + "date": "2026-01-29", + "value": 52.7 + }, + { + "date": "2026-02-06", + "value": 48.6 + }, + { + "date": "2026-02-12", + "value": 52.7 + }, + { + "date": "2026-02-18", + "value": 55.4 + }, + { + "date": "2026-02-24", + "value": 60.8 + }, + { + "date": "2026-02-30", + "value": 40.5 + }, + { + "date": "2026-03-04", + "value": 47.2 + }, + { + "date": "2026-03-10", + "value": 51.3 + }, + { + "date": "2026-03-16", + "value": 55.4 + }, + { + "date": "2026-03-22", + "value": 36.5 + }, + { + "date": "2026-03-28", + "value": 40.5 + }, + { + "date": "2026-04-05", + "value": 45.9 + }, + { + "date": "2026-04-11", + "value": 51.3 + }, + { + "date": "2026-04-17", + "value": 31.1 + }, + { + "date": "2026-04-23", + "value": 36.5 + }, + { + "date": "2026-04-29", + "value": 39.2 + }, + { + "date": "2026-05-06", + "value": 58.1 + }, + { + "date": "2026-05-12", + "value": 37.8 + }, + { + "date": "2026-05-18", + "value": 43.2 + }, + { + "date": "2026-05-24", + "value": 45.9 + }, + { + "date": "2026-05-30", + "value": 50.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 49.7, + "median": 49.3, + "p10": 22.7, + "p25": 32.4, + "p75": 66.6, + "p90": 76.8, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 62.8, + "median": 59.4, + "p10": 32.3, + "p25": 40.2, + "p75": 82.1, + "p90": 96.0, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 51.7, + "median": 56.7, + "p10": 20.0, + "p25": 33.8, + "p75": 72.2, + "p90": 81.5, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 50.6, + "median": 42.5, + "p10": 24.3, + "p25": 30.4, + "p75": 62.8, + "p90": 83.4, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 59.7, + "median": 64.8, + "p10": 18.6, + "p25": 40.5, + "p75": 74.2, + "p90": 98.6, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 60.1, + "median": 41.9, + "p10": 25.9, + "p25": 28.4, + "p75": 73.6, + "p90": 108.8, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 51.0, + "median": 52.7, + "p10": 42.7, + "p25": 45.9, + "p75": 55.4, + "p90": 58.6, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 45.4, + "median": 43.2, + "p10": 38.1, + "p25": 40.5, + "p75": 51.3, + "p90": 53.7, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 40.2, + "median": 39.2, + "p10": 33.2, + "p25": 36.5, + "p75": 43.2, + "p90": 48.1, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 46.2, + "median": 45.9, + "p10": 40.0, + "p25": 43.2, + "p75": 50.0, + "p90": 52.4, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 45.1, + "median": 44.6, + "p10": 39.4, + "p25": 41.9, + "p75": 48.6, + "p90": 51.0, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 51.6, + "median": 52.7, + "p10": 43.7, + "p25": 48.6, + "p75": 55.4, + "p90": 58.6, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 46.2, + "median": 47.2, + "p10": 38.1, + "p25": 40.5, + "p75": 51.3, + "p90": 53.7, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 40.8, + "median": 39.2, + "p10": 33.2, + "p25": 36.5, + "p75": 45.9, + "p90": 49.1, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 47.0, + "median": 45.9, + "p10": 40.0, + "p25": 43.2, + "p75": 50.0, + "p90": 54.8, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 59.3, + "median": 55.4, + "std": 25.8, + "min": 5.4, + "max": 155.2, + "p25": 46.3, + "p75": 67.5, + "p85": 72.9, + "p95": 110.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 7.425, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 54.0 + }, + { + "date": "2022-06-15", + "value": 29.7 + }, + { + "date": "2022-06-25", + "value": 91.8 + }, + { + "date": "2023-03-08", + "value": 5.4 + }, + { + "date": "2023-03-15", + "value": 74.2 + }, + { + "date": "2023-03-22", + "value": 155.2 + }, + { + "date": "2023-03-29", + "value": 40.5 + }, + { + "date": "2023-11-06", + "value": 83.7 + }, + { + "date": "2023-11-13", + "value": 24.3 + }, + { + "date": "2023-11-20", + "value": 114.8 + }, + { + "date": "2024-06-03", + "value": 47.2 + }, + { + "date": "2024-06-10", + "value": 97.2 + }, + { + "date": "2024-06-17", + "value": 13.5 + }, + { + "date": "2024-06-24", + "value": 64.8 + }, + { + "date": "2024-06-30", + "value": 128.2 + }, + { + "date": "2025-01-07", + "value": 37.8 + }, + { + "date": "2025-01-14", + "value": 70.2 + }, + { + "date": "2025-01-21", + "value": 20.2 + }, + { + "date": "2025-01-28", + "value": 105.3 + }, + { + "date": "2025-08-04", + "value": 56.7 + }, + { + "date": "2025-08-08", + "value": 10.8 + }, + { + "date": "2025-08-12", + "value": 87.8 + }, + { + "date": "2025-08-16", + "value": 44.6 + }, + { + "date": "2025-08-20", + "value": 135.0 + }, + { + "date": "2025-08-24", + "value": 27.0 + }, + { + "date": "2025-09-06", + "value": 55.4 + }, + { + "date": "2025-09-12", + "value": 60.8 + }, + { + "date": "2025-09-18", + "value": 64.8 + }, + { + "date": "2025-09-24", + "value": 70.2 + }, + { + "date": "2025-09-30", + "value": 45.9 + }, + { + "date": "2025-10-04", + "value": 54.0 + }, + { + "date": "2025-10-10", + "value": 59.4 + }, + { + "date": "2025-10-16", + "value": 64.8 + }, + { + "date": "2025-10-22", + "value": 40.5 + }, + { + "date": "2025-10-28", + "value": 45.9 + }, + { + "date": "2025-11-05", + "value": 67.5 + }, + { + "date": "2025-11-11", + "value": 72.9 + }, + { + "date": "2025-11-17", + "value": 48.6 + }, + { + "date": "2025-11-23", + "value": 55.4 + }, + { + "date": "2025-11-29", + "value": 59.4 + }, + { + "date": "2025-12-06", + "value": 67.5 + }, + { + "date": "2025-12-12", + "value": 43.2 + }, + { + "date": "2025-12-18", + "value": 48.6 + }, + { + "date": "2025-12-24", + "value": 52.7 + }, + { + "date": "2025-12-30", + "value": 58.1 + }, + { + "date": "2026-01-04", + "value": 37.8 + }, + { + "date": "2026-01-10", + "value": 43.2 + }, + { + "date": "2026-01-16", + "value": 47.2 + }, + { + "date": "2026-01-22", + "value": 51.3 + }, + { + "date": "2026-01-28", + "value": 56.7 + }, + { + "date": "2026-02-05", + "value": 52.7 + }, + { + "date": "2026-02-11", + "value": 55.4 + }, + { + "date": "2026-02-17", + "value": 60.8 + }, + { + "date": "2026-02-23", + "value": 64.8 + }, + { + "date": "2026-02-29", + "value": 70.2 + }, + { + "date": "2026-03-06", + "value": 50.0 + }, + { + "date": "2026-03-12", + "value": 54.0 + }, + { + "date": "2026-03-18", + "value": 59.4 + }, + { + "date": "2026-03-24", + "value": 64.8 + }, + { + "date": "2026-03-30", + "value": 40.5 + }, + { + "date": "2026-04-04", + "value": 63.5 + }, + { + "date": "2026-04-10", + "value": 67.5 + }, + { + "date": "2026-04-16", + "value": 72.9 + }, + { + "date": "2026-04-22", + "value": 48.6 + }, + { + "date": "2026-04-28", + "value": 55.4 + }, + { + "date": "2026-05-05", + "value": 62.1 + }, + { + "date": "2026-05-11", + "value": 67.5 + }, + { + "date": "2026-05-17", + "value": 43.2 + }, + { + "date": "2026-05-23", + "value": 48.6 + }, + { + "date": "2026-05-29", + "value": 52.7 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 58.5, + "median": 54.0, + "p10": 34.6, + "p25": 41.9, + "p75": 72.9, + "p90": 84.2, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 68.9, + "median": 57.4, + "p10": 15.9, + "p25": 31.7, + "p75": 94.5, + "p90": 131.0, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 74.2, + "median": 83.7, + "p10": 36.2, + "p25": 54.0, + "p75": 99.2, + "p90": 108.5, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 70.2, + "median": 64.8, + "p10": 27.0, + "p25": 47.2, + "p75": 97.2, + "p90": 115.8, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 58.5, + "median": 54.0, + "p10": 25.5, + "p25": 33.5, + "p75": 79.0, + "p90": 94.8, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 60.3, + "median": 50.6, + "p10": 18.9, + "p25": 31.5, + "p75": 80.1, + "p90": 111.4, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 59.4, + "median": 60.8, + "p10": 49.7, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 52.9, + "median": 54.0, + "p10": 42.7, + "p25": 45.9, + "p75": 59.4, + "p90": 62.6, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 60.8, + "median": 59.4, + "p10": 51.3, + "p25": 55.4, + "p75": 67.5, + "p90": 70.7, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 54.0, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 58.1, + "p90": 63.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 47.2, + "median": 47.2, + "p10": 40.0, + "p25": 43.2, + "p75": 51.3, + "p90": 54.5, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 60.8, + "median": 60.8, + "p10": 53.7, + "p25": 55.4, + "p75": 64.8, + "p90": 68.0, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 53.7, + "median": 54.0, + "p10": 44.3, + "p25": 50.0, + "p75": 59.4, + "p90": 62.6, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 61.6, + "median": 63.5, + "p10": 51.3, + "p25": 55.4, + "p75": 67.5, + "p90": 70.7, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 54.8, + "median": 52.7, + "p10": 45.4, + "p25": 48.6, + "p75": 62.1, + "p90": 65.3, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 5.9, + "median": 5.4, + "std": 2.4, + "min": 1.4, + "max": 18.9, + "p25": 4.5, + "p75": 6.8, + "p85": 6.8, + "p95": 8.9 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 4.1 + }, + { + "date": "2022-07-05", + "value": 6.8 + }, + { + "date": "2022-10-12", + "value": 2.7 + }, + { + "date": "2023-01-20", + "value": 9.5 + }, + { + "date": "2023-04-15", + "value": 5.4 + }, + { + "date": "2023-07-28", + "value": 8.1 + }, + { + "date": "2023-10-05", + "value": 4.1 + }, + { + "date": "2024-01-12", + "value": 18.9 + }, + { + "date": "2024-04-22", + "value": 5.4 + }, + { + "date": "2024-07-10", + "value": 10.8 + }, + { + "date": "2024-10-18", + "value": 4.1 + }, + { + "date": "2025-01-25", + "value": 6.8 + }, + { + "date": "2025-05-08", + "value": 1.4 + }, + { + "date": "2025-08-15", + "value": 8.1 + }, + { + "date": "2025-09-04", + "value": 4.1 + }, + { + "date": "2025-09-10", + "value": 5.4 + }, + { + "date": "2025-09-16", + "value": 5.4 + }, + { + "date": "2025-09-22", + "value": 5.4 + }, + { + "date": "2025-10-05", + "value": 4.1 + }, + { + "date": "2025-10-11", + "value": 5.4 + }, + { + "date": "2025-10-17", + "value": 5.4 + }, + { + "date": "2025-10-23", + "value": 5.4 + }, + { + "date": "2025-11-06", + "value": 5.4 + }, + { + "date": "2025-11-12", + "value": 6.8 + }, + { + "date": "2025-11-18", + "value": 6.8 + }, + { + "date": "2025-11-24", + "value": 6.8 + }, + { + "date": "2025-12-04", + "value": 5.4 + }, + { + "date": "2025-12-10", + "value": 6.8 + }, + { + "date": "2025-12-16", + "value": 6.8 + }, + { + "date": "2025-12-22", + "value": 4.1 + }, + { + "date": "2026-01-05", + "value": 5.4 + }, + { + "date": "2026-01-11", + "value": 6.8 + }, + { + "date": "2026-01-17", + "value": 4.1 + }, + { + "date": "2026-01-23", + "value": 4.1 + }, + { + "date": "2026-02-06", + "value": 6.8 + }, + { + "date": "2026-02-12", + "value": 4.1 + }, + { + "date": "2026-02-18", + "value": 5.4 + }, + { + "date": "2026-02-24", + "value": 5.4 + }, + { + "date": "2026-03-04", + "value": 4.1 + }, + { + "date": "2026-03-10", + "value": 4.1 + }, + { + "date": "2026-03-16", + "value": 5.4 + }, + { + "date": "2026-03-22", + "value": 5.4 + }, + { + "date": "2026-04-05", + "value": 5.4 + }, + { + "date": "2026-04-11", + "value": 5.4 + }, + { + "date": "2026-04-17", + "value": 6.8 + }, + { + "date": "2026-04-23", + "value": 6.8 + }, + { + "date": "2026-05-06", + "value": 5.4 + }, + { + "date": "2026-05-12", + "value": 5.4 + }, + { + "date": "2026-05-18", + "value": 6.8 + }, + { + "date": "2026-05-24", + "value": 6.8 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-01", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-04", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-07", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2023-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2024-04", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-01", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-10", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 6.5, + "median": 6.8, + "p10": 5.8, + "p25": 6.5, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2025-12", + "mean": 5.8, + "median": 6.1, + "p10": 4.5, + "p25": 5.1, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2026-01", + "mean": 5.1, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.8, + "p90": 6.3, + "n": 4 + }, + { + "month": "2026-02", + "mean": 5.4, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.8, + "p90": 6.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 6.1, + "median": 6.1, + "p10": 5.4, + "p25": 5.4, + "p75": 6.8, + "p90": 6.8, + "n": 4 + }, + { + "month": "2026-05", + "mean": 6.1, + "median": 6.1, + "p10": 5.4, + "p25": 5.4, + "p75": 6.8, + "p90": 6.8, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 23.5, + "median": 21.6, + "std": 12.2, + "min": 2.7, + "max": 74.2, + "p25": 17.6, + "p75": 25.7, + "p85": 27.5, + "p95": 50.0 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 16.875, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 16.2 + }, + { + "date": "2022-05-15", + "value": 33.8 + }, + { + "date": "2022-05-22", + "value": 10.8 + }, + { + "date": "2022-11-03", + "value": 47.2 + }, + { + "date": "2022-11-10", + "value": 20.2 + }, + { + "date": "2022-11-18", + "value": 6.8 + }, + { + "date": "2022-11-25", + "value": 29.7 + }, + { + "date": "2023-05-08", + "value": 24.3 + }, + { + "date": "2023-05-15", + "value": 54.0 + }, + { + "date": "2023-05-22", + "value": 13.5 + }, + { + "date": "2023-11-06", + "value": 74.2 + }, + { + "date": "2023-11-13", + "value": 2.7 + }, + { + "date": "2023-11-20", + "value": 37.8 + }, + { + "date": "2023-11-27", + "value": 20.2 + }, + { + "date": "2023-11-30", + "value": 10.8 + }, + { + "date": "2024-05-06", + "value": 27.0 + }, + { + "date": "2024-05-13", + "value": 60.8 + }, + { + "date": "2024-05-20", + "value": 16.2 + }, + { + "date": "2024-05-27", + "value": 4.1 + }, + { + "date": "2024-11-04", + "value": 24.3 + }, + { + "date": "2024-11-11", + "value": 40.5 + }, + { + "date": "2024-11-18", + "value": 10.8 + }, + { + "date": "2025-05-05", + "value": 29.7 + }, + { + "date": "2025-05-09", + "value": 47.2 + }, + { + "date": "2025-05-13", + "value": 6.8 + }, + { + "date": "2025-05-17", + "value": 20.2 + }, + { + "date": "2025-05-21", + "value": 56.7 + }, + { + "date": "2025-05-25", + "value": 13.5 + }, + { + "date": "2025-09-05", + "value": 18.9 + }, + { + "date": "2025-09-11", + "value": 21.6 + }, + { + "date": "2025-09-17", + "value": 23.0 + }, + { + "date": "2025-09-23", + "value": 24.3 + }, + { + "date": "2025-09-29", + "value": 25.7 + }, + { + "date": "2025-10-06", + "value": 18.9 + }, + { + "date": "2025-10-12", + "value": 20.2 + }, + { + "date": "2025-10-18", + "value": 21.6 + }, + { + "date": "2025-10-24", + "value": 24.3 + }, + { + "date": "2025-10-30", + "value": 14.9 + }, + { + "date": "2025-11-04", + "value": 24.3 + }, + { + "date": "2025-11-10", + "value": 25.7 + }, + { + "date": "2025-11-16", + "value": 27.0 + }, + { + "date": "2025-11-22", + "value": 18.9 + }, + { + "date": "2025-11-28", + "value": 20.2 + }, + { + "date": "2025-12-05", + "value": 23.0 + }, + { + "date": "2025-12-11", + "value": 25.7 + }, + { + "date": "2025-12-17", + "value": 16.2 + }, + { + "date": "2025-12-23", + "value": 18.9 + }, + { + "date": "2025-12-29", + "value": 20.2 + }, + { + "date": "2026-01-06", + "value": 23.0 + }, + { + "date": "2026-01-12", + "value": 14.9 + }, + { + "date": "2026-01-18", + "value": 16.2 + }, + { + "date": "2026-01-24", + "value": 17.6 + }, + { + "date": "2026-01-30", + "value": 18.9 + }, + { + "date": "2026-02-04", + "value": 17.6 + }, + { + "date": "2026-02-10", + "value": 18.9 + }, + { + "date": "2026-02-16", + "value": 21.6 + }, + { + "date": "2026-02-22", + "value": 23.0 + }, + { + "date": "2026-02-28", + "value": 24.3 + }, + { + "date": "2026-03-05", + "value": 17.6 + }, + { + "date": "2026-03-11", + "value": 18.9 + }, + { + "date": "2026-03-17", + "value": 20.2 + }, + { + "date": "2026-03-23", + "value": 21.6 + }, + { + "date": "2026-03-29", + "value": 24.3 + }, + { + "date": "2026-04-06", + "value": 21.6 + }, + { + "date": "2026-04-12", + "value": 24.3 + }, + { + "date": "2026-04-18", + "value": 25.7 + }, + { + "date": "2026-04-24", + "value": 27.0 + }, + { + "date": "2026-04-30", + "value": 18.9 + }, + { + "date": "2026-05-04", + "value": 21.6 + }, + { + "date": "2026-05-10", + "value": 23.0 + }, + { + "date": "2026-05-16", + "value": 25.7 + }, + { + "date": "2026-05-22", + "value": 16.2 + }, + { + "date": "2026-05-28", + "value": 18.9 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 20.2, + "median": 16.2, + "p10": 11.9, + "p25": 13.5, + "p75": 25.0, + "p90": 30.2, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 26.1, + "median": 25.0, + "p10": 10.8, + "p25": 16.9, + "p75": 34.2, + "p90": 42.0, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 30.6, + "median": 24.3, + "p10": 15.7, + "p25": 18.9, + "p75": 39.2, + "p90": 48.1, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 29.2, + "median": 20.2, + "p10": 5.9, + "p25": 10.8, + "p75": 37.8, + "p90": 59.7, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 27.0, + "median": 21.6, + "p10": 7.7, + "p25": 13.2, + "p75": 35.5, + "p90": 50.6, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 25.2, + "median": 24.3, + "p10": 13.5, + "p25": 17.6, + "p75": 32.4, + "p90": 37.3, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 29.0, + "median": 25.0, + "p10": 10.1, + "p25": 15.3, + "p75": 42.9, + "p90": 52.0, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 22.7, + "median": 23.0, + "p10": 20.0, + "p25": 21.6, + "p75": 24.3, + "p90": 25.1, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 20.0, + "median": 20.2, + "p10": 16.5, + "p25": 18.9, + "p75": 21.6, + "p90": 23.2, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 23.2, + "median": 24.3, + "p10": 19.4, + "p25": 20.2, + "p75": 25.7, + "p90": 26.5, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 20.8, + "median": 20.2, + "p10": 17.3, + "p25": 18.9, + "p75": 23.0, + "p90": 24.6, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 18.1, + "median": 17.6, + "p10": 15.4, + "p25": 16.2, + "p75": 18.9, + "p90": 21.3, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 21.1, + "median": 21.6, + "p10": 18.1, + "p25": 18.9, + "p75": 23.0, + "p90": 23.8, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 20.5, + "median": 20.2, + "p10": 18.1, + "p25": 18.9, + "p75": 21.6, + "p90": 23.2, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 23.5, + "median": 24.3, + "p10": 20.0, + "p25": 21.6, + "p75": 25.7, + "p90": 26.5, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 21.1, + "median": 21.6, + "p10": 17.3, + "p25": 18.9, + "p75": 23.0, + "p90": 24.6, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 4.3, + "median": 4.1, + "std": 1.9, + "min": 0.0, + "max": 13.5, + "p25": 4.1, + "p75": 5.4, + "p85": 5.4, + "p95": 7.0 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 2.7 + }, + { + "date": "2022-06-10", + "value": 4.1 + }, + { + "date": "2022-07-15", + "value": 1.4 + }, + { + "date": "2022-08-22", + "value": 5.4 + }, + { + "date": "2022-10-05", + "value": 2.7 + }, + { + "date": "2022-11-18", + "value": 6.8 + }, + { + "date": "2023-01-10", + "value": 4.1 + }, + { + "date": "2023-03-25", + "value": 9.5 + }, + { + "date": "2023-05-12", + "value": 2.7 + }, + { + "date": "2023-07-08", + "value": 5.4 + }, + { + "date": "2023-09-15", + "value": 1.4 + }, + { + "date": "2023-11-22", + "value": 4.1 + }, + { + "date": "2024-01-18", + "value": 13.5 + }, + { + "date": "2024-03-08", + "value": 4.1 + }, + { + "date": "2024-05-15", + "value": 2.7 + }, + { + "date": "2024-07-22", + "value": 6.8 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 5.4 + }, + { + "date": "2025-01-15", + "value": 4.1 + }, + { + "date": "2025-03-20", + "value": 2.7 + }, + { + "date": "2025-05-28", + "value": 8.1 + }, + { + "date": "2025-08-05", + "value": 4.1 + }, + { + "date": "2025-09-05", + "value": 5.4 + }, + { + "date": "2025-09-11", + "value": 5.4 + }, + { + "date": "2025-09-17", + "value": 4.1 + }, + { + "date": "2025-09-23", + "value": 4.1 + }, + { + "date": "2025-10-06", + "value": 5.4 + }, + { + "date": "2025-10-12", + "value": 2.7 + }, + { + "date": "2025-10-18", + "value": 4.1 + }, + { + "date": "2025-10-24", + "value": 4.1 + }, + { + "date": "2025-11-04", + "value": 2.7 + }, + { + "date": "2025-11-10", + "value": 2.7 + }, + { + "date": "2025-11-16", + "value": 4.1 + }, + { + "date": "2025-11-22", + "value": 4.1 + }, + { + "date": "2025-12-05", + "value": 4.1 + }, + { + "date": "2025-12-11", + "value": 4.1 + }, + { + "date": "2025-12-17", + "value": 4.1 + }, + { + "date": "2025-12-23", + "value": 5.4 + }, + { + "date": "2026-01-06", + "value": 4.1 + }, + { + "date": "2026-01-12", + "value": 4.1 + }, + { + "date": "2026-01-18", + "value": 4.1 + }, + { + "date": "2026-01-24", + "value": 5.4 + }, + { + "date": "2026-02-04", + "value": 5.4 + }, + { + "date": "2026-02-10", + "value": 5.4 + }, + { + "date": "2026-02-16", + "value": 5.4 + }, + { + "date": "2026-02-22", + "value": 4.1 + }, + { + "date": "2026-03-05", + "value": 4.1 + }, + { + "date": "2026-03-11", + "value": 5.4 + }, + { + "date": "2026-03-17", + "value": 2.7 + }, + { + "date": "2026-03-23", + "value": 4.1 + }, + { + "date": "2026-04-06", + "value": 4.1 + }, + { + "date": "2026-04-12", + "value": 2.7 + }, + { + "date": "2026-04-18", + "value": 2.7 + }, + { + "date": "2026-04-24", + "value": 4.1 + }, + { + "date": "2026-05-04", + "value": 4.1 + }, + { + "date": "2026-05-10", + "value": 4.1 + }, + { + "date": "2026-05-16", + "value": 4.1 + }, + { + "date": "2026-05-22", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-06", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2022-08", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-11", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-03", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2023-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2025-05", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.4, + "median": 3.4, + "p10": 2.7, + "p25": 2.7, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-12", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-02", + "mean": 5.1, + "median": 5.4, + "p10": 4.5, + "p25": 5.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.4, + "median": 3.4, + "p10": 2.7, + "p25": 2.7, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 4.6, + "median": 4.1, + "std": 2.4, + "min": 0.0, + "max": 17.6, + "p25": 4.1, + "p75": 5.4, + "p85": 5.4, + "p95": 8.4 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 2.7 + }, + { + "date": "2022-06-13", + "value": 1.4 + }, + { + "date": "2022-07-16", + "value": 4.1 + }, + { + "date": "2022-08-26", + "value": 2.7 + }, + { + "date": "2022-10-07", + "value": 6.8 + }, + { + "date": "2022-11-23", + "value": 2.7 + }, + { + "date": "2023-01-13", + "value": 5.4 + }, + { + "date": "2023-04-01", + "value": 4.1 + }, + { + "date": "2023-05-14", + "value": 8.1 + }, + { + "date": "2023-07-12", + "value": 2.7 + }, + { + "date": "2023-09-16", + "value": 17.6 + }, + { + "date": "2023-11-25", + "value": 4.1 + }, + { + "date": "2024-01-28", + "value": 9.5 + }, + { + "date": "2024-03-11", + "value": 1.4 + }, + { + "date": "2024-05-17", + "value": 5.4 + }, + { + "date": "2024-07-27", + "value": 6.8 + }, + { + "date": "2024-09-10", + "value": 2.7 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 4.1 + }, + { + "date": "2025-03-22", + "value": 10.8 + }, + { + "date": "2025-06-03", + "value": 2.7 + }, + { + "date": "2025-08-08", + "value": 6.8 + }, + { + "date": "2025-09-04", + "value": 2.7 + }, + { + "date": "2025-09-10", + "value": 4.1 + }, + { + "date": "2025-09-16", + "value": 4.1 + }, + { + "date": "2025-09-22", + "value": 4.1 + }, + { + "date": "2025-10-05", + "value": 4.1 + }, + { + "date": "2025-10-11", + "value": 4.1 + }, + { + "date": "2025-10-17", + "value": 5.4 + }, + { + "date": "2025-10-23", + "value": 5.4 + }, + { + "date": "2025-11-06", + "value": 4.1 + }, + { + "date": "2025-11-12", + "value": 4.1 + }, + { + "date": "2025-11-18", + "value": 4.1 + }, + { + "date": "2025-11-24", + "value": 5.4 + }, + { + "date": "2025-12-04", + "value": 4.1 + }, + { + "date": "2025-12-10", + "value": 4.1 + }, + { + "date": "2025-12-16", + "value": 4.1 + }, + { + "date": "2025-12-22", + "value": 2.7 + }, + { + "date": "2026-01-05", + "value": 5.4 + }, + { + "date": "2026-01-11", + "value": 5.4 + }, + { + "date": "2026-01-17", + "value": 4.1 + }, + { + "date": "2026-01-23", + "value": 4.1 + }, + { + "date": "2026-02-06", + "value": 5.4 + }, + { + "date": "2026-02-12", + "value": 2.7 + }, + { + "date": "2026-02-18", + "value": 4.1 + }, + { + "date": "2026-02-24", + "value": 4.1 + }, + { + "date": "2026-03-04", + "value": 4.1 + }, + { + "date": "2026-03-10", + "value": 4.1 + }, + { + "date": "2026-03-16", + "value": 4.1 + }, + { + "date": "2026-03-22", + "value": 5.4 + }, + { + "date": "2026-04-05", + "value": 4.1 + }, + { + "date": "2026-04-11", + "value": 4.1 + }, + { + "date": "2026-04-17", + "value": 4.1 + }, + { + "date": "2026-04-23", + "value": 4.1 + }, + { + "date": "2026-05-06", + "value": 4.1 + }, + { + "date": "2026-05-12", + "value": 4.1 + }, + { + "date": "2026-05-18", + "value": 4.1 + }, + { + "date": "2026-05-24", + "value": 4.1 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2022-07", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-01", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2023-05", + "mean": 8.1, + "median": 8.1, + "p10": 8.1, + "p25": 8.1, + "p75": 8.1, + "p90": 8.1, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 17.6, + "median": 17.6, + "p10": 17.6, + "p25": 17.6, + "p75": 17.6, + "p90": 17.6, + "n": 1 + }, + { + "month": "2023-11", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2024-01", + "mean": 9.5, + "median": 9.5, + "p10": 9.5, + "p25": 9.5, + "p75": 9.5, + "p90": 9.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.4, + "median": 1.4, + "p10": 1.4, + "p25": 1.4, + "p75": 1.4, + "p90": 1.4, + "n": 1 + }, + { + "month": "2024-05", + "mean": 5.4, + "median": 5.4, + "p10": 5.4, + "p25": 5.4, + "p75": 5.4, + "p90": 5.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 1 + }, + { + "month": "2025-03", + "mean": 10.8, + "median": 10.8, + "p10": 10.8, + "p25": 10.8, + "p75": 10.8, + "p90": 10.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.7, + "median": 2.7, + "p10": 2.7, + "p25": 2.7, + "p75": 2.7, + "p90": 2.7, + "n": 1 + }, + { + "month": "2025-08", + "mean": 6.8, + "median": 6.8, + "p10": 6.8, + "p25": 6.8, + "p75": 6.8, + "p90": 6.8, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.8, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.8, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.7, + "median": 4.7, + "p10": 4.1, + "p25": 4.1, + "p75": 5.4, + "p90": 5.4, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.1, + "median": 4.1, + "p10": 3.1, + "p25": 3.8, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.5, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.5, + "p90": 5.0, + "n": 4 + }, + { + "month": "2026-04", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + }, + { + "month": "2026-05", + "mean": 4.1, + "median": 4.1, + "p10": 4.1, + "p25": 4.1, + "p75": 4.1, + "p90": 4.1, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 17.1, + "median": 16.2, + "std": 7.6, + "min": 2.7, + "max": 56.7, + "p25": 13.5, + "p75": 18.9, + "p85": 20.2, + "p95": 27.5 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 38.475, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 10.8 + }, + { + "date": "2023-03-25", + "value": 29.7 + }, + { + "date": "2023-09-20", + "value": 56.7 + }, + { + "date": "2024-03-15", + "value": 8.1 + }, + { + "date": "2024-03-28", + "value": 24.3 + }, + { + "date": "2024-09-05", + "value": 37.8 + }, + { + "date": "2024-09-15", + "value": 16.2 + }, + { + "date": "2024-09-25", + "value": 2.7 + }, + { + "date": "2025-03-10", + "value": 20.2 + }, + { + "date": "2025-03-22", + "value": 6.8 + }, + { + "date": "2025-07-08", + "value": 27.0 + }, + { + "date": "2025-07-22", + "value": 5.4 + }, + { + "date": "2025-09-05", + "value": 18.9 + }, + { + "date": "2025-09-11", + "value": 20.2 + }, + { + "date": "2025-09-17", + "value": 13.5 + }, + { + "date": "2025-09-23", + "value": 14.9 + }, + { + "date": "2025-09-29", + "value": 16.2 + }, + { + "date": "2025-10-06", + "value": 18.9 + }, + { + "date": "2025-10-12", + "value": 10.8 + }, + { + "date": "2025-10-18", + "value": 13.5 + }, + { + "date": "2025-10-24", + "value": 14.9 + }, + { + "date": "2025-10-30", + "value": 14.9 + }, + { + "date": "2025-11-04", + "value": 13.5 + }, + { + "date": "2025-11-10", + "value": 16.2 + }, + { + "date": "2025-11-16", + "value": 16.2 + }, + { + "date": "2025-11-22", + "value": 17.6 + }, + { + "date": "2025-11-28", + "value": 18.9 + }, + { + "date": "2025-12-05", + "value": 13.5 + }, + { + "date": "2025-12-11", + "value": 14.9 + }, + { + "date": "2025-12-17", + "value": 16.2 + }, + { + "date": "2025-12-23", + "value": 17.6 + }, + { + "date": "2025-12-29", + "value": 18.9 + }, + { + "date": "2026-01-06", + "value": 17.6 + }, + { + "date": "2026-01-12", + "value": 18.9 + }, + { + "date": "2026-01-18", + "value": 20.2 + }, + { + "date": "2026-01-24", + "value": 21.6 + }, + { + "date": "2026-01-30", + "value": 14.9 + }, + { + "date": "2026-02-04", + "value": 17.6 + }, + { + "date": "2026-02-10", + "value": 18.9 + }, + { + "date": "2026-02-16", + "value": 20.2 + }, + { + "date": "2026-02-22", + "value": 13.5 + }, + { + "date": "2026-02-28", + "value": 14.9 + }, + { + "date": "2026-03-05", + "value": 17.6 + }, + { + "date": "2026-03-11", + "value": 18.9 + }, + { + "date": "2026-03-17", + "value": 10.8 + }, + { + "date": "2026-03-23", + "value": 13.5 + }, + { + "date": "2026-03-29", + "value": 14.9 + }, + { + "date": "2026-04-06", + "value": 21.6 + }, + { + "date": "2026-04-12", + "value": 13.5 + }, + { + "date": "2026-04-18", + "value": 16.2 + }, + { + "date": "2026-04-24", + "value": 16.2 + }, + { + "date": "2026-04-30", + "value": 17.6 + }, + { + "date": "2026-05-04", + "value": 12.2 + }, + { + "date": "2026-05-10", + "value": 13.5 + }, + { + "date": "2026-05-16", + "value": 14.9 + }, + { + "date": "2026-05-22", + "value": 16.2 + }, + { + "date": "2026-05-28", + "value": 17.6 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 20.2, + "median": 20.2, + "p10": 12.7, + "p25": 15.5, + "p75": 25.0, + "p90": 27.8, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 16.2, + "median": 16.2, + "p10": 9.7, + "p25": 12.2, + "p75": 20.2, + "p90": 22.7, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 18.9, + "median": 16.2, + "p10": 5.4, + "p25": 9.5, + "p75": 27.0, + "p90": 33.5, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 13.5, + "median": 13.5, + "p10": 8.1, + "p25": 10.1, + "p75": 16.9, + "p90": 18.9, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 16.2, + "median": 16.2, + "p10": 7.6, + "p25": 10.8, + "p75": 21.6, + "p90": 24.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 16.7, + "median": 16.2, + "p10": 14.0, + "p25": 14.9, + "p75": 18.9, + "p90": 19.7, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 14.6, + "median": 14.9, + "p10": 11.9, + "p25": 13.5, + "p75": 14.9, + "p90": 17.3, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 16.5, + "median": 16.2, + "p10": 14.6, + "p25": 16.2, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 16.2, + "median": 16.2, + "p10": 14.0, + "p25": 14.9, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 18.6, + "median": 18.9, + "p10": 15.9, + "p25": 17.6, + "p75": 20.2, + "p90": 21.1, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 17.0, + "median": 17.6, + "p10": 14.0, + "p25": 14.9, + "p75": 18.9, + "p90": 19.7, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 15.1, + "median": 14.9, + "p10": 11.9, + "p25": 13.5, + "p75": 17.6, + "p90": 18.4, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 17.0, + "median": 16.2, + "p10": 14.6, + "p25": 16.2, + "p75": 17.6, + "p90": 20.0, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 14.9, + "median": 14.9, + "p10": 12.7, + "p25": 13.5, + "p75": 16.2, + "p90": 17.0, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 28.2, + "median": 28.4, + "std": 6.2, + "min": 16.2, + "max": 51.3, + "p25": 25.0, + "p75": 31.1, + "p85": 33.6, + "p95": 35.9 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 24.3 + }, + { + "date": "2023-10-12", + "value": 33.8 + }, + { + "date": "2024-04-08", + "value": 16.2 + }, + { + "date": "2024-09-20", + "value": 51.3 + }, + { + "date": "2024-10-15", + "value": 27.0 + }, + { + "date": "2025-03-25", + "value": 20.2 + }, + { + "date": "2025-04-10", + "value": 37.8 + }, + { + "date": "2025-07-30", + "value": 32.4 + }, + { + "date": "2025-09-04", + "value": 23.0 + }, + { + "date": "2025-09-10", + "value": 25.7 + }, + { + "date": "2025-09-16", + "value": 28.4 + }, + { + "date": "2025-10-05", + "value": 23.0 + }, + { + "date": "2025-10-11", + "value": 25.7 + }, + { + "date": "2025-10-17", + "value": 27.0 + }, + { + "date": "2025-11-06", + "value": 29.7 + }, + { + "date": "2025-11-12", + "value": 31.1 + }, + { + "date": "2025-11-18", + "value": 33.8 + }, + { + "date": "2025-12-04", + "value": 28.4 + }, + { + "date": "2025-12-10", + "value": 31.1 + }, + { + "date": "2025-12-16", + "value": 33.8 + }, + { + "date": "2026-01-05", + "value": 28.4 + }, + { + "date": "2026-01-11", + "value": 31.1 + }, + { + "date": "2026-01-17", + "value": 18.9 + }, + { + "date": "2026-02-06", + "value": 35.1 + }, + { + "date": "2026-02-12", + "value": 23.0 + }, + { + "date": "2026-02-18", + "value": 25.7 + }, + { + "date": "2026-03-04", + "value": 20.2 + }, + { + "date": "2026-03-10", + "value": 23.0 + }, + { + "date": "2026-03-16", + "value": 25.7 + }, + { + "date": "2026-04-05", + "value": 27.0 + }, + { + "date": "2026-04-11", + "value": 29.7 + }, + { + "date": "2026-04-17", + "value": 31.1 + }, + { + "date": "2026-05-06", + "value": 27.0 + }, + { + "date": "2026-05-12", + "value": 28.4 + }, + { + "date": "2026-05-18", + "value": 31.1 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 24.3, + "median": 24.3, + "p10": 24.3, + "p25": 24.3, + "p75": 24.3, + "p90": 24.3, + "n": 1 + }, + { + "month": "2023-10", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-04", + "mean": 16.2, + "median": 16.2, + "p10": 16.2, + "p25": 16.2, + "p75": 16.2, + "p90": 16.2, + "n": 1 + }, + { + "month": "2024-09", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-10", + "mean": 27.0, + "median": 27.0, + "p10": 27.0, + "p25": 27.0, + "p75": 27.0, + "p90": 27.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-07", + "mean": 32.4, + "median": 32.4, + "p10": 32.4, + "p25": 32.4, + "p75": 32.4, + "p90": 32.4, + "n": 1 + }, + { + "month": "2025-09", + "mean": 25.7, + "median": 25.7, + "p10": 23.5, + "p25": 24.3, + "p75": 27.0, + "p90": 27.8, + "n": 3 + }, + { + "month": "2025-10", + "mean": 25.2, + "median": 25.7, + "p10": 23.5, + "p25": 24.3, + "p75": 26.3, + "p90": 26.7, + "n": 3 + }, + { + "month": "2025-11", + "mean": 31.5, + "median": 31.1, + "p10": 30.0, + "p25": 30.4, + "p75": 32.4, + "p90": 33.2, + "n": 3 + }, + { + "month": "2025-12", + "mean": 31.1, + "median": 31.1, + "p10": 28.9, + "p25": 29.7, + "p75": 32.4, + "p90": 33.2, + "n": 3 + }, + { + "month": "2026-01", + "mean": 26.1, + "median": 28.4, + "p10": 20.8, + "p25": 23.6, + "p75": 29.7, + "p90": 30.5, + "n": 3 + }, + { + "month": "2026-02", + "mean": 27.9, + "median": 25.7, + "p10": 23.5, + "p25": 24.3, + "p75": 30.4, + "p90": 33.2, + "n": 3 + }, + { + "month": "2026-03", + "mean": 23.0, + "median": 23.0, + "p10": 20.8, + "p25": 21.6, + "p75": 24.3, + "p90": 25.1, + "n": 3 + }, + { + "month": "2026-04", + "mean": 29.3, + "median": 29.7, + "p10": 27.5, + "p25": 28.4, + "p75": 30.4, + "p90": 30.8, + "n": 3 + }, + { + "month": "2026-05", + "mean": 28.8, + "median": 28.4, + "p10": 27.3, + "p25": 27.7, + "p75": 29.7, + "p90": 30.5, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 42.3, + "median": 41.2, + "std": 9.6, + "min": 20.2, + "max": 74.2, + "p25": 36.5, + "p75": 48.6, + "p85": 51.3, + "p95": 56.6 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 37.8 + }, + { + "date": "2022-11-30", + "value": 47.2 + }, + { + "date": "2023-03-15", + "value": 29.7 + }, + { + "date": "2023-07-10", + "value": 56.7 + }, + { + "date": "2023-10-25", + "value": 40.5 + }, + { + "date": "2024-02-08", + "value": 74.2 + }, + { + "date": "2024-05-20", + "value": 33.8 + }, + { + "date": "2024-08-12", + "value": 51.3 + }, + { + "date": "2024-11-05", + "value": 20.2 + }, + { + "date": "2025-01-22", + "value": 43.2 + }, + { + "date": "2025-04-10", + "value": 37.8 + }, + { + "date": "2025-06-18", + "value": 60.8 + }, + { + "date": "2025-07-15", + "value": 40.5 + }, + { + "date": "2025-08-05", + "value": 29.7 + }, + { + "date": "2025-09-05", + "value": 48.6 + }, + { + "date": "2025-09-10", + "value": 51.3 + }, + { + "date": "2025-09-11", + "value": 52.7 + }, + { + "date": "2025-09-17", + "value": 35.1 + }, + { + "date": "2025-10-06", + "value": 48.6 + }, + { + "date": "2025-10-12", + "value": 31.1 + }, + { + "date": "2025-10-18", + "value": 35.1 + }, + { + "date": "2025-11-04", + "value": 36.5 + }, + { + "date": "2025-11-10", + "value": 41.9 + }, + { + "date": "2025-11-16", + "value": 44.6 + }, + { + "date": "2025-12-05", + "value": 36.5 + }, + { + "date": "2025-12-11", + "value": 39.2 + }, + { + "date": "2025-12-17", + "value": 43.2 + }, + { + "date": "2026-01-06", + "value": 35.1 + }, + { + "date": "2026-01-12", + "value": 39.2 + }, + { + "date": "2026-01-18", + "value": 41.9 + }, + { + "date": "2026-02-04", + "value": 44.6 + }, + { + "date": "2026-02-10", + "value": 48.6 + }, + { + "date": "2026-02-16", + "value": 52.7 + }, + { + "date": "2026-03-05", + "value": 44.6 + }, + { + "date": "2026-03-11", + "value": 48.6 + }, + { + "date": "2026-03-17", + "value": 31.1 + }, + { + "date": "2026-04-06", + "value": 54.0 + }, + { + "date": "2026-04-12", + "value": 36.5 + }, + { + "date": "2026-04-18", + "value": 41.9 + }, + { + "date": "2026-05-04", + "value": 32.4 + }, + { + "date": "2026-05-10", + "value": 36.5 + }, + { + "date": "2026-05-16", + "value": 39.2 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2022-11", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2023-03", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1 + }, + { + "month": "2023-10", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2024-02", + "mean": 74.2, + "median": 74.2, + "p10": 74.2, + "p25": 74.2, + "p75": 74.2, + "p90": 74.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 33.8, + "median": 33.8, + "p10": 33.8, + "p25": 33.8, + "p75": 33.8, + "p90": 33.8, + "n": 1 + }, + { + "month": "2024-08", + "mean": 51.3, + "median": 51.3, + "p10": 51.3, + "p25": 51.3, + "p75": 51.3, + "p90": 51.3, + "n": 1 + }, + { + "month": "2024-11", + "mean": 20.2, + "median": 20.2, + "p10": 20.2, + "p25": 20.2, + "p75": 20.2, + "p90": 20.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 43.2, + "median": 43.2, + "p10": 43.2, + "p25": 43.2, + "p75": 43.2, + "p90": 43.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 60.8, + "median": 60.8, + "p10": 60.8, + "p25": 60.8, + "p75": 60.8, + "p90": 60.8, + "n": 1 + }, + { + "month": "2025-07", + "mean": 40.5, + "median": 40.5, + "p10": 40.5, + "p25": 40.5, + "p75": 40.5, + "p90": 40.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 29.7, + "median": 29.7, + "p10": 29.7, + "p25": 29.7, + "p75": 29.7, + "p90": 29.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 47.0, + "median": 50.0, + "p10": 39.2, + "p25": 45.2, + "p75": 51.7, + "p90": 52.2, + "n": 4 + }, + { + "month": "2025-10", + "mean": 38.2, + "median": 35.1, + "p10": 31.9, + "p25": 33.1, + "p75": 41.9, + "p90": 45.9, + "n": 3 + }, + { + "month": "2025-11", + "mean": 40.9, + "median": 41.9, + "p10": 37.5, + "p25": 39.2, + "p75": 43.2, + "p90": 44.0, + "n": 3 + }, + { + "month": "2025-12", + "mean": 39.6, + "median": 39.2, + "p10": 37.0, + "p25": 37.8, + "p75": 41.2, + "p90": 42.4, + "n": 3 + }, + { + "month": "2026-01", + "mean": 38.7, + "median": 39.2, + "p10": 35.9, + "p25": 37.1, + "p75": 40.5, + "p90": 41.3, + "n": 3 + }, + { + "month": "2026-02", + "mean": 48.6, + "median": 48.6, + "p10": 45.4, + "p25": 46.6, + "p75": 50.6, + "p90": 51.8, + "n": 3 + }, + { + "month": "2026-03", + "mean": 41.4, + "median": 44.6, + "p10": 33.8, + "p25": 37.8, + "p75": 46.6, + "p90": 47.8, + "n": 3 + }, + { + "month": "2026-04", + "mean": 44.1, + "median": 41.9, + "p10": 37.5, + "p25": 39.2, + "p75": 47.9, + "p90": 51.6, + "n": 3 + }, + { + "month": "2026-05", + "mean": 36.0, + "median": 36.5, + "p10": 33.2, + "p25": 34.4, + "p75": 37.8, + "p90": 38.6, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 60.8, + "median": 59.4, + "std": 18.9, + "min": 13.5, + "max": 128.2, + "p25": 48.6, + "p75": 66.2, + "p85": 71.6, + "p95": 91.3 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 38.475, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 56.7 + }, + { + "date": "2023-05-05", + "value": 87.8 + }, + { + "date": "2023-05-20", + "value": 37.8 + }, + { + "date": "2024-01-10", + "value": 128.2 + }, + { + "date": "2024-01-25", + "value": 47.2 + }, + { + "date": "2024-08-15", + "value": 13.5 + }, + { + "date": "2025-02-05", + "value": 105.3 + }, + { + "date": "2025-02-18", + "value": 74.2 + }, + { + "date": "2025-08-10", + "value": 56.7 + }, + { + "date": "2025-08-20", + "value": 43.2 + }, + { + "date": "2025-09-06", + "value": 52.7 + }, + { + "date": "2025-09-12", + "value": 56.7 + }, + { + "date": "2025-09-18", + "value": 62.1 + }, + { + "date": "2025-10-04", + "value": 66.2 + }, + { + "date": "2025-10-10", + "value": 71.6 + }, + { + "date": "2025-10-16", + "value": 77.0 + }, + { + "date": "2025-11-05", + "value": 64.8 + }, + { + "date": "2025-11-11", + "value": 70.2 + }, + { + "date": "2025-11-17", + "value": 45.9 + }, + { + "date": "2025-12-06", + "value": 64.8 + }, + { + "date": "2025-12-12", + "value": 40.5 + }, + { + "date": "2025-12-18", + "value": 45.9 + }, + { + "date": "2026-01-04", + "value": 48.6 + }, + { + "date": "2026-01-10", + "value": 55.4 + }, + { + "date": "2026-01-16", + "value": 58.1 + }, + { + "date": "2026-02-05", + "value": 48.6 + }, + { + "date": "2026-02-11", + "value": 52.7 + }, + { + "date": "2026-02-17", + "value": 56.7 + }, + { + "date": "2026-03-06", + "value": 62.1 + }, + { + "date": "2026-03-12", + "value": 66.2 + }, + { + "date": "2026-03-18", + "value": 71.6 + }, + { + "date": "2026-04-04", + "value": 60.8 + }, + { + "date": "2026-04-10", + "value": 64.8 + }, + { + "date": "2026-04-16", + "value": 70.2 + }, + { + "date": "2026-05-05", + "value": 59.4 + }, + { + "date": "2026-05-11", + "value": 64.8 + }, + { + "date": "2026-05-17", + "value": 40.5 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 56.7, + "median": 56.7, + "p10": 56.7, + "p25": 56.7, + "p75": 56.7, + "p90": 56.7, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 62.8, + "median": 62.8, + "p10": 42.8, + "p25": 50.4, + "p75": 75.3, + "p90": 82.8, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 87.8, + "median": 87.8, + "p10": 55.4, + "p25": 67.5, + "p75": 108.0, + "p90": 120.2, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 13.5, + "median": 13.5, + "p10": 13.5, + "p25": 13.5, + "p75": 13.5, + "p90": 13.5, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 89.8, + "median": 89.8, + "p10": 77.4, + "p25": 82.1, + "p75": 97.6, + "p90": 102.2, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 50.0, + "median": 50.0, + "p10": 44.6, + "p25": 46.6, + "p75": 53.3, + "p90": 55.4, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 57.1, + "median": 56.7, + "p10": 53.5, + "p25": 54.7, + "p75": 59.4, + "p90": 61.0, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 71.6, + "median": 71.6, + "p10": 67.2, + "p25": 68.9, + "p75": 74.2, + "p90": 75.9, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 60.3, + "median": 64.8, + "p10": 49.7, + "p25": 55.4, + "p75": 67.5, + "p90": 69.1, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 50.4, + "median": 45.9, + "p10": 41.6, + "p25": 43.2, + "p75": 55.4, + "p90": 61.0, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 54.0, + "median": 55.4, + "p10": 50.0, + "p25": 52.0, + "p75": 56.7, + "p90": 57.5, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 52.7, + "median": 52.7, + "p10": 49.4, + "p25": 50.6, + "p75": 54.7, + "p90": 55.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 66.6, + "median": 66.2, + "p10": 62.9, + "p25": 64.1, + "p75": 68.9, + "p90": 70.5, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 65.2, + "median": 64.8, + "p10": 61.6, + "p25": 62.8, + "p75": 67.5, + "p90": 69.1, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 54.9, + "median": 59.4, + "p10": 44.3, + "p25": 50.0, + "p75": 62.1, + "p90": 63.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ] + } + ], + "rollups": { + "total_dwell_cost": 683368.2, + "top_dwell_costs": [ + { + "product_id": "meadow-espresso", + "node_id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "period_cost": 86981.96 + }, + { + "product_id": "summit-medium-roast", + "node_id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "period_cost": 76367.03 + }, + { + "product_id": "harbor-dark-roast", + "node_id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "period_cost": 65127.69 + }, + { + "product_id": "riverside-decaf", + "node_id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "period_cost": 53888.35 + }, + { + "product_id": "meadow-espresso", + "node_id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "period_cost": 37852.29 + } + ], + "top_planning_mismatches": [ + { + "product_id": "meadow-espresso", + "node_id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "deviation_pct": 440.0 + }, + { + "product_id": "meadow-espresso", + "node_id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "deviation_pct": 382.9 + }, + { + "product_id": "summit-medium-roast", + "node_id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "deviation_pct": 372.0 + }, + { + "product_id": "summit-medium-roast", + "node_id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "deviation_pct": 321.4 + }, + { + "product_id": "harbor-dark-roast", + "node_id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "deviation_pct": 300.0 + } + ], + "bad_planning_param_count": 30 + } +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/sites.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/sites.json new file mode 100644 index 00000000000..6dc7a646026 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/sites.json @@ -0,0 +1,6 @@ +[ + { + "slug": "harbor-roastery", + "name": "Harbor Roastery" + } +] diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/graph.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/graph.json new file mode 100644 index 00000000000..6fb785a8900 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/graph.json @@ -0,0 +1,16588 @@ +{ + "product_id": "summit-medium-roast", + "product_name": "Summit Medium Roast", + "nodes": [ + { + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 59, + "mean": 47.4, + "median": 47.2, + "std": 15.7, + "min": 9.4, + "max": 123.9, + "p25": 41.3, + "p75": 53.1, + "p85": 56.6, + "p95": 65.8 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "cost": null, + "observations": [ + { + "date": "2022-03-15", + "value": 64.9 + }, + { + "date": "2022-06-10", + "value": 49.6 + }, + { + "date": "2022-09-22", + "value": 9.4 + }, + { + "date": "2022-12-05", + "value": 74.3 + }, + { + "date": "2023-02-14", + "value": 44.8 + }, + { + "date": "2023-05-30", + "value": 26.0 + }, + { + "date": "2023-08-17", + "value": 83.8 + }, + { + "date": "2023-11-02", + "value": 35.4 + }, + { + "date": "2024-01-25", + "value": 53.1 + }, + { + "date": "2024-04-11", + "value": 21.2 + }, + { + "date": "2024-07-09", + "value": 123.9 + }, + { + "date": "2024-10-03", + "value": 41.3 + }, + { + "date": "2025-01-20", + "value": 14.2 + }, + { + "date": "2025-04-08", + "value": 56.6 + }, + { + "date": "2025-09-05", + "value": 46.0 + }, + { + "date": "2025-09-11", + "value": 48.4 + }, + { + "date": "2025-09-17", + "value": 51.9 + }, + { + "date": "2025-09-23", + "value": 56.6 + }, + { + "date": "2025-09-29", + "value": 60.2 + }, + { + "date": "2025-10-06", + "value": 43.7 + }, + { + "date": "2025-10-12", + "value": 47.2 + }, + { + "date": "2025-10-18", + "value": 51.9 + }, + { + "date": "2025-10-24", + "value": 55.5 + }, + { + "date": "2025-10-30", + "value": 36.6 + }, + { + "date": "2025-11-04", + "value": 42.5 + }, + { + "date": "2025-11-10", + "value": 47.2 + }, + { + "date": "2025-11-16", + "value": 50.7 + }, + { + "date": "2025-11-22", + "value": 31.9 + }, + { + "date": "2025-11-28", + "value": 36.6 + }, + { + "date": "2025-12-05", + "value": 54.3 + }, + { + "date": "2025-12-11", + "value": 57.8 + }, + { + "date": "2025-12-17", + "value": 38.9 + }, + { + "date": "2025-12-23", + "value": 43.7 + }, + { + "date": "2025-12-29", + "value": 46.0 + }, + { + "date": "2026-01-06", + "value": 53.1 + }, + { + "date": "2026-01-12", + "value": 34.2 + }, + { + "date": "2026-01-18", + "value": 38.9 + }, + { + "date": "2026-01-24", + "value": 41.3 + }, + { + "date": "2026-01-30", + "value": 44.8 + }, + { + "date": "2026-02-04", + "value": 41.3 + }, + { + "date": "2026-02-10", + "value": 46.0 + }, + { + "date": "2026-02-16", + "value": 48.4 + }, + { + "date": "2026-02-22", + "value": 51.9 + }, + { + "date": "2026-02-28", + "value": 56.6 + }, + { + "date": "2026-03-05", + "value": 41.3 + }, + { + "date": "2026-03-11", + "value": 43.7 + }, + { + "date": "2026-03-17", + "value": 47.2 + }, + { + "date": "2026-03-23", + "value": 51.9 + }, + { + "date": "2026-03-29", + "value": 55.5 + }, + { + "date": "2026-04-06", + "value": 38.9 + }, + { + "date": "2026-04-12", + "value": 42.5 + }, + { + "date": "2026-04-18", + "value": 47.2 + }, + { + "date": "2026-04-24", + "value": 50.7 + }, + { + "date": "2026-04-30", + "value": 31.9 + }, + { + "date": "2026-05-04", + "value": 49.6 + }, + { + "date": "2026-05-10", + "value": 54.3 + }, + { + "date": "2026-05-16", + "value": 57.8 + }, + { + "date": "2026-05-22", + "value": 38.9 + }, + { + "date": "2026-05-28", + "value": 43.7 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2022-06", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1 + }, + { + "month": "2022-09", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2022-12", + "mean": 74.3, + "median": 74.3, + "p10": 74.3, + "p25": 74.3, + "p75": 74.3, + "p90": 74.3, + "n": 1 + }, + { + "month": "2023-02", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 83.8, + "median": 83.8, + "p10": 83.8, + "p25": 83.8, + "p75": 83.8, + "p90": 83.8, + "n": 1 + }, + { + "month": "2023-11", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2024-01", + "mean": 53.1, + "median": 53.1, + "p10": 53.1, + "p25": 53.1, + "p75": 53.1, + "p90": 53.1, + "n": 1 + }, + { + "month": "2024-04", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2024-07", + "mean": 123.9, + "median": 123.9, + "p10": 123.9, + "p25": 123.9, + "p75": 123.9, + "p90": 123.9, + "n": 1 + }, + { + "month": "2024-10", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2025-09", + "mean": 52.6, + "median": 51.9, + "p10": 47.0, + "p25": 48.4, + "p75": 56.6, + "p90": 58.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 47.0, + "median": 47.2, + "p10": 39.4, + "p25": 43.7, + "p75": 51.9, + "p90": 54.0, + "n": 5 + }, + { + "month": "2025-11", + "mean": 41.8, + "median": 42.5, + "p10": 33.7, + "p25": 36.6, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2025-12", + "mean": 48.1, + "median": 46.0, + "p10": 40.8, + "p25": 43.7, + "p75": 54.3, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-01", + "mean": 42.5, + "median": 41.3, + "p10": 36.1, + "p25": 38.9, + "p75": 44.8, + "p90": 49.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 48.9, + "median": 48.4, + "p10": 43.2, + "p25": 46.0, + "p75": 51.9, + "p90": 54.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 47.9, + "median": 47.2, + "p10": 42.2, + "p25": 43.7, + "p75": 51.9, + "p90": 54.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 42.2, + "median": 42.5, + "p10": 34.7, + "p25": 38.9, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 48.9, + "median": 49.6, + "p10": 40.8, + "p25": 43.7, + "p75": 54.3, + "p90": 56.4, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 63, + "mean": 39.4, + "median": 38.9, + "std": 13.5, + "min": 5.9, + "max": 96.8, + "p25": 33.0, + "p75": 44.8, + "p85": 48.0, + "p95": 60.9 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "cost": null, + "observations": [ + { + "date": "2022-02-08", + "value": 37.8 + }, + { + "date": "2022-04-19", + "value": 56.6 + }, + { + "date": "2022-07-11", + "value": 5.9 + }, + { + "date": "2022-09-28", + "value": 79.1 + }, + { + "date": "2022-12-15", + "value": 29.5 + }, + { + "date": "2023-03-07", + "value": 48.4 + }, + { + "date": "2023-05-22", + "value": 17.7 + }, + { + "date": "2023-08-09", + "value": 96.8 + }, + { + "date": "2023-10-30", + "value": 44.8 + }, + { + "date": "2024-01-16", + "value": 23.6 + }, + { + "date": "2024-03-25", + "value": 61.4 + }, + { + "date": "2024-06-12", + "value": 11.8 + }, + { + "date": "2024-08-28", + "value": 51.9 + }, + { + "date": "2024-11-14", + "value": 33.0 + }, + { + "date": "2025-01-06", + "value": 41.3 + }, + { + "date": "2025-03-18", + "value": 21.2 + }, + { + "date": "2025-05-29", + "value": 64.9 + }, + { + "date": "2025-08-12", + "value": 30.7 + }, + { + "date": "2025-09-04", + "value": 30.7 + }, + { + "date": "2025-09-10", + "value": 34.2 + }, + { + "date": "2025-09-16", + "value": 36.6 + }, + { + "date": "2025-09-22", + "value": 40.1 + }, + { + "date": "2025-09-28", + "value": 43.7 + }, + { + "date": "2025-10-05", + "value": 30.7 + }, + { + "date": "2025-10-11", + "value": 33.0 + }, + { + "date": "2025-10-17", + "value": 36.6 + }, + { + "date": "2025-10-23", + "value": 38.9 + }, + { + "date": "2025-10-29", + "value": 42.5 + }, + { + "date": "2025-11-06", + "value": 38.9 + }, + { + "date": "2025-11-12", + "value": 42.5 + }, + { + "date": "2025-11-18", + "value": 44.8 + }, + { + "date": "2025-11-24", + "value": 49.6 + }, + { + "date": "2025-11-30", + "value": 33.0 + }, + { + "date": "2025-12-04", + "value": 37.8 + }, + { + "date": "2025-12-10", + "value": 41.3 + }, + { + "date": "2025-12-16", + "value": 44.8 + }, + { + "date": "2025-12-22", + "value": 28.3 + }, + { + "date": "2025-12-28", + "value": 33.0 + }, + { + "date": "2026-01-05", + "value": 47.2 + }, + { + "date": "2026-01-11", + "value": 50.7 + }, + { + "date": "2026-01-17", + "value": 34.2 + }, + { + "date": "2026-01-23", + "value": 38.9 + }, + { + "date": "2026-01-29", + "value": 41.3 + }, + { + "date": "2026-02-06", + "value": 47.2 + }, + { + "date": "2026-02-12", + "value": 30.7 + }, + { + "date": "2026-02-18", + "value": 34.2 + }, + { + "date": "2026-02-24", + "value": 36.6 + }, + { + "date": "2026-02-30", + "value": 40.1 + }, + { + "date": "2026-03-04", + "value": 26.0 + }, + { + "date": "2026-03-10", + "value": 30.7 + }, + { + "date": "2026-03-16", + "value": 33.0 + }, + { + "date": "2026-03-22", + "value": 36.6 + }, + { + "date": "2026-03-28", + "value": 38.9 + }, + { + "date": "2026-04-05", + "value": 36.6 + }, + { + "date": "2026-04-11", + "value": 38.9 + }, + { + "date": "2026-04-17", + "value": 42.5 + }, + { + "date": "2026-04-23", + "value": 44.8 + }, + { + "date": "2026-04-29", + "value": 49.6 + }, + { + "date": "2026-05-06", + "value": 35.4 + }, + { + "date": "2026-05-12", + "value": 37.8 + }, + { + "date": "2026-05-18", + "value": 41.3 + }, + { + "date": "2026-05-24", + "value": 44.8 + }, + { + "date": "2026-05-30", + "value": 28.3 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2022-04", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-09", + "mean": 79.1, + "median": 79.1, + "p10": 79.1, + "p25": 79.1, + "p75": 79.1, + "p90": 79.1, + "n": 1 + }, + { + "month": "2022-12", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 48.4, + "median": 48.4, + "p10": 48.4, + "p25": 48.4, + "p75": 48.4, + "p90": 48.4, + "n": 1 + }, + { + "month": "2023-05", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2023-08", + "mean": 96.8, + "median": 96.8, + "p10": 96.8, + "p25": 96.8, + "p75": 96.8, + "p90": 96.8, + "n": 1 + }, + { + "month": "2023-10", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 23.6, + "median": 23.6, + "p10": 23.6, + "p25": 23.6, + "p75": 23.6, + "p90": 23.6, + "n": 1 + }, + { + "month": "2024-03", + "mean": 61.4, + "median": 61.4, + "p10": 61.4, + "p25": 61.4, + "p75": 61.4, + "p90": 61.4, + "n": 1 + }, + { + "month": "2024-06", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1 + }, + { + "month": "2024-08", + "mean": 51.9, + "median": 51.9, + "p10": 51.9, + "p25": 51.9, + "p75": 51.9, + "p90": 51.9, + "n": 1 + }, + { + "month": "2024-11", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2025-03", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2025-05", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2025-08", + "mean": 30.7, + "median": 30.7, + "p10": 30.7, + "p25": 30.7, + "p75": 30.7, + "p90": 30.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 37.1, + "median": 36.6, + "p10": 32.1, + "p25": 34.2, + "p75": 40.1, + "p90": 42.2, + "n": 5 + }, + { + "month": "2025-10", + "mean": 36.3, + "median": 36.6, + "p10": 31.6, + "p25": 33.0, + "p75": 38.9, + "p90": 41.1, + "n": 5 + }, + { + "month": "2025-11", + "mean": 41.8, + "median": 42.5, + "p10": 35.4, + "p25": 38.9, + "p75": 44.8, + "p90": 47.7, + "n": 5 + }, + { + "month": "2025-12", + "mean": 37.1, + "median": 37.8, + "p10": 30.2, + "p25": 33.0, + "p75": 41.3, + "p90": 43.4, + "n": 5 + }, + { + "month": "2026-01", + "mean": 42.5, + "median": 41.3, + "p10": 36.1, + "p25": 38.9, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2026-02", + "mean": 37.8, + "median": 36.6, + "p10": 32.1, + "p25": 34.2, + "p75": 40.1, + "p90": 44.4, + "n": 5 + }, + { + "month": "2026-03", + "mean": 33.0, + "median": 33.0, + "p10": 27.8, + "p25": 30.7, + "p75": 36.6, + "p90": 38.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 42.5, + "median": 42.5, + "p10": 37.5, + "p25": 38.9, + "p75": 44.8, + "p90": 47.7, + "n": 5 + }, + { + "month": "2026-05", + "mean": 37.5, + "median": 37.8, + "p10": 31.2, + "p25": 35.4, + "p75": 41.3, + "p90": 43.4, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 55, + "mean": 30.8, + "median": 29.5, + "std": 9.4, + "min": 8.3, + "max": 73.2, + "p25": 26.5, + "p75": 34.2, + "p85": 35.4, + "p95": 43.1 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "cost": null, + "observations": [ + { + "date": "2022-05-03", + "value": 41.3 + }, + { + "date": "2022-10-18", + "value": 18.9 + }, + { + "date": "2023-01-24", + "value": 73.2 + }, + { + "date": "2023-06-15", + "value": 8.3 + }, + { + "date": "2023-09-28", + "value": 47.2 + }, + { + "date": "2024-02-12", + "value": 29.5 + }, + { + "date": "2024-05-07", + "value": 56.6 + }, + { + "date": "2024-09-19", + "value": 14.2 + }, + { + "date": "2025-02-04", + "value": 35.4 + }, + { + "date": "2025-06-10", + "value": 16.5 + }, + { + "date": "2025-09-06", + "value": 35.4 + }, + { + "date": "2025-09-12", + "value": 22.4 + }, + { + "date": "2025-09-18", + "value": 26.0 + }, + { + "date": "2025-09-24", + "value": 27.1 + }, + { + "date": "2025-09-30", + "value": 29.5 + }, + { + "date": "2025-10-04", + "value": 27.1 + }, + { + "date": "2025-10-10", + "value": 29.5 + }, + { + "date": "2025-10-16", + "value": 31.9 + }, + { + "date": "2025-10-22", + "value": 34.2 + }, + { + "date": "2025-10-28", + "value": 36.6 + }, + { + "date": "2025-11-05", + "value": 27.1 + }, + { + "date": "2025-11-11", + "value": 29.5 + }, + { + "date": "2025-11-17", + "value": 31.9 + }, + { + "date": "2025-11-23", + "value": 34.2 + }, + { + "date": "2025-11-29", + "value": 36.6 + }, + { + "date": "2025-12-06", + "value": 26.0 + }, + { + "date": "2025-12-12", + "value": 28.3 + }, + { + "date": "2025-12-18", + "value": 30.7 + }, + { + "date": "2025-12-24", + "value": 33.0 + }, + { + "date": "2025-12-30", + "value": 21.2 + }, + { + "date": "2026-01-04", + "value": 33.0 + }, + { + "date": "2026-01-10", + "value": 35.4 + }, + { + "date": "2026-01-16", + "value": 37.8 + }, + { + "date": "2026-01-22", + "value": 26.0 + }, + { + "date": "2026-01-28", + "value": 28.3 + }, + { + "date": "2026-02-05", + "value": 31.9 + }, + { + "date": "2026-02-11", + "value": 35.4 + }, + { + "date": "2026-02-17", + "value": 22.4 + }, + { + "date": "2026-02-23", + "value": 26.0 + }, + { + "date": "2026-02-29", + "value": 27.1 + }, + { + "date": "2026-03-06", + "value": 40.1 + }, + { + "date": "2026-03-12", + "value": 27.1 + }, + { + "date": "2026-03-18", + "value": 29.5 + }, + { + "date": "2026-03-24", + "value": 31.9 + }, + { + "date": "2026-03-30", + "value": 34.2 + }, + { + "date": "2026-04-04", + "value": 23.6 + }, + { + "date": "2026-04-10", + "value": 27.1 + }, + { + "date": "2026-04-16", + "value": 29.5 + }, + { + "date": "2026-04-22", + "value": 31.9 + }, + { + "date": "2026-04-28", + "value": 34.2 + }, + { + "date": "2026-05-05", + "value": 23.6 + }, + { + "date": "2026-05-11", + "value": 26.0 + }, + { + "date": "2026-05-17", + "value": 28.3 + }, + { + "date": "2026-05-23", + "value": 30.7 + }, + { + "date": "2026-05-29", + "value": 33.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2022-10", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2023-01", + "mean": 73.2, + "median": 73.2, + "p10": 73.2, + "p25": 73.2, + "p75": 73.2, + "p90": 73.2, + "n": 1 + }, + { + "month": "2023-06", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-09", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2024-02", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2024-09", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2025-02", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2025-06", + "mean": 16.5, + "median": 16.5, + "p10": 16.5, + "p25": 16.5, + "p75": 16.5, + "p90": 16.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 28.1, + "median": 27.1, + "p10": 23.8, + "p25": 26.0, + "p75": 29.5, + "p90": 33.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 31.9, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 35.6, + "n": 5 + }, + { + "month": "2025-11", + "mean": 31.9, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 35.6, + "n": 5 + }, + { + "month": "2025-12", + "mean": 27.8, + "median": 28.3, + "p10": 23.1, + "p25": 26.0, + "p75": 30.7, + "p90": 32.1, + "n": 5 + }, + { + "month": "2026-01", + "mean": 32.1, + "median": 33.0, + "p10": 26.9, + "p25": 28.3, + "p75": 35.4, + "p90": 36.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 28.6, + "median": 27.1, + "p10": 23.8, + "p25": 26.0, + "p75": 31.9, + "p90": 34.0, + "n": 5 + }, + { + "month": "2026-03", + "mean": 32.6, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 37.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.3, + "median": 29.5, + "p10": 25.0, + "p25": 27.1, + "p75": 31.9, + "p90": 33.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 28.3, + "median": 28.3, + "p10": 24.5, + "p25": 26.0, + "p75": 30.7, + "p90": 32.1, + "n": 5 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "material": "90000100001", + "plant": "PL-A", + "stats": { + "n": 83, + "mean": 57.0, + "median": 54.3, + "std": 23.4, + "min": 5.9, + "max": 153.4, + "p25": 45.4, + "p75": 64.3, + "p85": 72.0, + "p95": 103.5 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "cost": { + "unit_price": 3.776, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "observations": [ + { + "date": "2022-04-02", + "value": 41.3 + }, + { + "date": "2022-04-15", + "value": 73.2 + }, + { + "date": "2022-04-28", + "value": 21.2 + }, + { + "date": "2022-08-05", + "value": 103.8 + }, + { + "date": "2022-08-12", + "value": 49.6 + }, + { + "date": "2022-08-20", + "value": 64.9 + }, + { + "date": "2022-08-28", + "value": 35.4 + }, + { + "date": "2023-01-10", + "value": 85.0 + }, + { + "date": "2023-01-22", + "value": 29.5 + }, + { + "date": "2023-01-30", + "value": 56.6 + }, + { + "date": "2023-06-05", + "value": 17.7 + }, + { + "date": "2023-06-18", + "value": 112.1 + }, + { + "date": "2023-10-03", + "value": 153.4 + }, + { + "date": "2023-10-10", + "value": 53.1 + }, + { + "date": "2023-10-18", + "value": 44.8 + }, + { + "date": "2023-10-25", + "value": 76.7 + }, + { + "date": "2023-10-30", + "value": 26.0 + }, + { + "date": "2024-03-05", + "value": 92.0 + }, + { + "date": "2024-03-12", + "value": 5.9 + }, + { + "date": "2024-03-20", + "value": 64.9 + }, + { + "date": "2024-03-28", + "value": 47.2 + }, + { + "date": "2024-07-08", + "value": 33.0 + }, + { + "date": "2024-07-15", + "value": 100.3 + }, + { + "date": "2024-07-22", + "value": 59.0 + }, + { + "date": "2024-11-04", + "value": 129.8 + }, + { + "date": "2024-11-11", + "value": 37.8 + }, + { + "date": "2024-11-18", + "value": 80.2 + }, + { + "date": "2024-11-25", + "value": 53.1 + }, + { + "date": "2024-11-30", + "value": 108.6 + }, + { + "date": "2025-03-03", + "value": 23.6 + }, + { + "date": "2025-03-10", + "value": 68.4 + }, + { + "date": "2025-03-17", + "value": 41.3 + }, + { + "date": "2025-03-24", + "value": 49.6 + }, + { + "date": "2025-07-02", + "value": 88.5 + }, + { + "date": "2025-07-09", + "value": 14.2 + }, + { + "date": "2025-07-16", + "value": 56.6 + }, + { + "date": "2025-07-23", + "value": 70.8 + }, + { + "date": "2025-07-30", + "value": 44.8 + }, + { + "date": "2025-09-05", + "value": 57.8 + }, + { + "date": "2025-09-11", + "value": 63.7 + }, + { + "date": "2025-09-17", + "value": 40.1 + }, + { + "date": "2025-09-23", + "value": 46.0 + }, + { + "date": "2025-09-29", + "value": 49.6 + }, + { + "date": "2025-10-06", + "value": 72.0 + }, + { + "date": "2025-10-12", + "value": 48.4 + }, + { + "date": "2025-10-18", + "value": 54.3 + }, + { + "date": "2025-10-24", + "value": 57.8 + }, + { + "date": "2025-10-30", + "value": 62.5 + }, + { + "date": "2025-11-04", + "value": 42.5 + }, + { + "date": "2025-11-10", + "value": 48.4 + }, + { + "date": "2025-11-16", + "value": 51.9 + }, + { + "date": "2025-11-22", + "value": 56.6 + }, + { + "date": "2025-11-28", + "value": 61.4 + }, + { + "date": "2025-12-05", + "value": 42.5 + }, + { + "date": "2025-12-11", + "value": 46.0 + }, + { + "date": "2025-12-17", + "value": 50.7 + }, + { + "date": "2025-12-23", + "value": 55.5 + }, + { + "date": "2025-12-29", + "value": 60.2 + }, + { + "date": "2026-01-06", + "value": 55.5 + }, + { + "date": "2026-01-12", + "value": 59.0 + }, + { + "date": "2026-01-18", + "value": 63.7 + }, + { + "date": "2026-01-24", + "value": 68.4 + }, + { + "date": "2026-01-30", + "value": 46.0 + }, + { + "date": "2026-02-04", + "value": 53.1 + }, + { + "date": "2026-02-10", + "value": 57.8 + }, + { + "date": "2026-02-16", + "value": 63.7 + }, + { + "date": "2026-02-22", + "value": 40.1 + }, + { + "date": "2026-02-28", + "value": 46.0 + }, + { + "date": "2026-03-05", + "value": 66.1 + }, + { + "date": "2026-03-11", + "value": 72.0 + }, + { + "date": "2026-03-17", + "value": 48.4 + }, + { + "date": "2026-03-23", + "value": 54.3 + }, + { + "date": "2026-03-29", + "value": 57.8 + }, + { + "date": "2026-04-06", + "value": 66.1 + }, + { + "date": "2026-04-12", + "value": 42.5 + }, + { + "date": "2026-04-18", + "value": 48.4 + }, + { + "date": "2026-04-24", + "value": 51.9 + }, + { + "date": "2026-04-30", + "value": 56.6 + }, + { + "date": "2026-05-04", + "value": 37.8 + }, + { + "date": "2026-05-10", + "value": 42.5 + }, + { + "date": "2026-05-16", + "value": 46.0 + }, + { + "date": "2026-05-22", + "value": 50.7 + }, + { + "date": "2026-05-28", + "value": 55.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 45.2, + "median": 41.3, + "p10": 25.3, + "p25": 31.3, + "p75": 57.2, + "p90": 66.8, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 63.5, + "median": 57.2, + "p10": 39.6, + "p25": 46.0, + "p75": 74.7, + "p90": 92.2, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 57.0, + "median": 56.6, + "p10": 34.9, + "p25": 43.1, + "p75": 70.8, + "p90": 79.3, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 64.9, + "median": 64.9, + "p10": 27.1, + "p25": 41.3, + "p75": 88.5, + "p90": 102.7, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 70.8, + "median": 53.1, + "p10": 33.5, + "p25": 44.8, + "p75": 76.7, + "p90": 122.7, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 52.5, + "median": 56.0, + "p10": 18.3, + "p25": 36.9, + "p75": 71.7, + "p90": 83.9, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 64.1, + "median": 59.0, + "p10": 38.2, + "p25": 46.0, + "p75": 79.6, + "p90": 92.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 81.9, + "median": 80.2, + "p10": 43.9, + "p25": 53.1, + "p75": 108.6, + "p90": 121.3, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 45.8, + "median": 45.4, + "p10": 28.9, + "p25": 36.9, + "p75": 54.3, + "p90": 62.8, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 55.0, + "median": 56.6, + "p10": 26.4, + "p25": 44.8, + "p75": 70.8, + "p90": 81.4, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 51.4, + "median": 49.6, + "p10": 42.5, + "p25": 46.0, + "p75": 57.8, + "p90": 61.4, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 59.0, + "median": 57.8, + "p10": 50.7, + "p25": 54.3, + "p75": 62.5, + "p90": 68.2, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 52.2, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 51.0, + "median": 50.7, + "p10": 43.9, + "p25": 46.0, + "p75": 55.5, + "p90": 58.3, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 58.5, + "median": 59.0, + "p10": 49.8, + "p25": 55.5, + "p75": 63.7, + "p90": 66.6, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 52.2, + "median": 53.1, + "p10": 42.5, + "p25": 46.0, + "p75": 57.8, + "p90": 61.4, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 59.7, + "median": 57.8, + "p10": 50.7, + "p25": 54.3, + "p75": 66.1, + "p90": 69.6, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 53.1, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 56.6, + "p90": 62.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 46.5, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 50.7, + "p90": 53.6, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "material": "90000100002", + "plant": "PL-A", + "stats": { + "n": 69, + "mean": 43.2, + "median": 40.1, + "std": 18.6, + "min": 3.5, + "max": 115.6, + "p25": 33.0, + "p75": 48.4, + "p85": 53.1, + "p95": 81.7 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "cost": { + "unit_price": 2.124, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-02", + "value": 33.0 + }, + { + "date": "2022-05-10", + "value": 53.1 + }, + { + "date": "2022-05-18", + "value": 14.2 + }, + { + "date": "2022-05-25", + "value": 73.2 + }, + { + "date": "2023-02-06", + "value": 38.9 + }, + { + "date": "2023-02-14", + "value": 92.0 + }, + { + "date": "2023-02-22", + "value": 23.6 + }, + { + "date": "2023-02-28", + "value": 64.9 + }, + { + "date": "2023-09-05", + "value": 9.4 + }, + { + "date": "2023-09-15", + "value": 49.6 + }, + { + "date": "2023-09-25", + "value": 76.7 + }, + { + "date": "2024-04-03", + "value": 44.8 + }, + { + "date": "2024-04-10", + "value": 17.7 + }, + { + "date": "2024-04-17", + "value": 85.0 + }, + { + "date": "2024-04-24", + "value": 29.5 + }, + { + "date": "2024-10-02", + "value": 56.6 + }, + { + "date": "2024-10-09", + "value": 3.5 + }, + { + "date": "2024-10-16", + "value": 100.3 + }, + { + "date": "2024-10-23", + "value": 35.4 + }, + { + "date": "2024-10-30", + "value": 64.9 + }, + { + "date": "2025-04-07", + "value": 26.0 + }, + { + "date": "2025-04-14", + "value": 47.2 + }, + { + "date": "2025-04-21", + "value": 115.6 + }, + { + "date": "2025-04-28", + "value": 21.2 + }, + { + "date": "2025-09-04", + "value": 46.0 + }, + { + "date": "2025-09-10", + "value": 48.4 + }, + { + "date": "2025-09-16", + "value": 53.1 + }, + { + "date": "2025-09-22", + "value": 35.4 + }, + { + "date": "2025-09-28", + "value": 40.1 + }, + { + "date": "2025-10-05", + "value": 44.8 + }, + { + "date": "2025-10-11", + "value": 48.4 + }, + { + "date": "2025-10-17", + "value": 31.9 + }, + { + "date": "2025-10-23", + "value": 35.4 + }, + { + "date": "2025-10-29", + "value": 37.8 + }, + { + "date": "2025-11-06", + "value": 44.8 + }, + { + "date": "2025-11-12", + "value": 27.1 + }, + { + "date": "2025-11-18", + "value": 31.9 + }, + { + "date": "2025-11-24", + "value": 34.2 + }, + { + "date": "2025-11-30", + "value": 37.8 + }, + { + "date": "2025-12-04", + "value": 33.0 + }, + { + "date": "2025-12-10", + "value": 37.8 + }, + { + "date": "2025-12-16", + "value": 40.1 + }, + { + "date": "2025-12-22", + "value": 43.7 + }, + { + "date": "2025-12-28", + "value": 47.2 + }, + { + "date": "2026-01-05", + "value": 33.0 + }, + { + "date": "2026-01-11", + "value": 36.6 + }, + { + "date": "2026-01-17", + "value": 38.9 + }, + { + "date": "2026-01-23", + "value": 42.5 + }, + { + "date": "2026-01-29", + "value": 46.0 + }, + { + "date": "2026-02-06", + "value": 42.5 + }, + { + "date": "2026-02-12", + "value": 46.0 + }, + { + "date": "2026-02-18", + "value": 48.4 + }, + { + "date": "2026-02-24", + "value": 53.1 + }, + { + "date": "2026-02-30", + "value": 35.4 + }, + { + "date": "2026-03-04", + "value": 41.3 + }, + { + "date": "2026-03-10", + "value": 44.8 + }, + { + "date": "2026-03-16", + "value": 48.4 + }, + { + "date": "2026-03-22", + "value": 31.9 + }, + { + "date": "2026-03-28", + "value": 35.4 + }, + { + "date": "2026-04-05", + "value": 40.1 + }, + { + "date": "2026-04-11", + "value": 44.8 + }, + { + "date": "2026-04-17", + "value": 27.1 + }, + { + "date": "2026-04-23", + "value": 31.9 + }, + { + "date": "2026-04-29", + "value": 34.2 + }, + { + "date": "2026-05-06", + "value": 50.7 + }, + { + "date": "2026-05-12", + "value": 33.0 + }, + { + "date": "2026-05-18", + "value": 37.8 + }, + { + "date": "2026-05-24", + "value": 40.1 + }, + { + "date": "2026-05-30", + "value": 43.7 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 43.4, + "median": 43.1, + "p10": 19.8, + "p25": 28.3, + "p75": 58.2, + "p90": 67.1, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 54.9, + "median": 51.9, + "p10": 28.2, + "p25": 35.2, + "p75": 71.7, + "p90": 83.9, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 45.2, + "median": 49.6, + "p10": 17.5, + "p25": 29.5, + "p75": 63.1, + "p90": 71.3, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 44.2, + "median": 37.2, + "p10": 21.2, + "p25": 26.5, + "p75": 54.9, + "p90": 72.9, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 52.2, + "median": 56.6, + "p10": 16.3, + "p25": 35.4, + "p75": 64.9, + "p90": 86.1, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 52.5, + "median": 36.6, + "p10": 22.7, + "p25": 24.8, + "p75": 64.3, + "p90": 95.1, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 44.6, + "median": 46.0, + "p10": 37.3, + "p25": 40.1, + "p75": 48.4, + "p90": 51.2, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 39.6, + "median": 37.8, + "p10": 33.3, + "p25": 35.4, + "p75": 44.8, + "p90": 47.0, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 35.2, + "median": 34.2, + "p10": 29.0, + "p25": 31.9, + "p75": 37.8, + "p90": 42.0, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 40.4, + "median": 40.1, + "p10": 34.9, + "p25": 37.8, + "p75": 43.7, + "p90": 45.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 39.4, + "median": 38.9, + "p10": 34.5, + "p25": 36.6, + "p75": 42.5, + "p90": 44.6, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 45.1, + "median": 46.0, + "p10": 38.2, + "p25": 42.5, + "p75": 48.4, + "p90": 51.2, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 40.4, + "median": 41.3, + "p10": 33.3, + "p25": 35.4, + "p75": 44.8, + "p90": 47.0, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 35.6, + "median": 34.2, + "p10": 29.0, + "p25": 31.9, + "p75": 40.1, + "p90": 43.0, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 41.1, + "median": 40.1, + "p10": 34.9, + "p25": 37.8, + "p75": 43.7, + "p90": 47.9, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "material": "90000100003", + "plant": "PL-A", + "stats": { + "n": 70, + "mean": 51.8, + "median": 48.4, + "std": 22.5, + "min": 4.7, + "max": 135.7, + "p25": 40.5, + "p75": 59.0, + "p85": 63.7, + "p95": 96.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "cost": { + "unit_price": 6.49, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "observations": [ + { + "date": "2022-06-05", + "value": 47.2 + }, + { + "date": "2022-06-15", + "value": 26.0 + }, + { + "date": "2022-06-25", + "value": 80.2 + }, + { + "date": "2023-03-08", + "value": 4.7 + }, + { + "date": "2023-03-15", + "value": 64.9 + }, + { + "date": "2023-03-22", + "value": 135.7 + }, + { + "date": "2023-03-29", + "value": 35.4 + }, + { + "date": "2023-11-06", + "value": 73.2 + }, + { + "date": "2023-11-13", + "value": 21.2 + }, + { + "date": "2023-11-20", + "value": 100.3 + }, + { + "date": "2024-06-03", + "value": 41.3 + }, + { + "date": "2024-06-10", + "value": 85.0 + }, + { + "date": "2024-06-17", + "value": 11.8 + }, + { + "date": "2024-06-24", + "value": 56.6 + }, + { + "date": "2024-06-30", + "value": 112.1 + }, + { + "date": "2025-01-07", + "value": 33.0 + }, + { + "date": "2025-01-14", + "value": 61.4 + }, + { + "date": "2025-01-21", + "value": 17.7 + }, + { + "date": "2025-01-28", + "value": 92.0 + }, + { + "date": "2025-08-04", + "value": 49.6 + }, + { + "date": "2025-08-08", + "value": 9.4 + }, + { + "date": "2025-08-12", + "value": 76.7 + }, + { + "date": "2025-08-16", + "value": 38.9 + }, + { + "date": "2025-08-20", + "value": 118.0 + }, + { + "date": "2025-08-24", + "value": 23.6 + }, + { + "date": "2025-09-06", + "value": 48.4 + }, + { + "date": "2025-09-12", + "value": 53.1 + }, + { + "date": "2025-09-18", + "value": 56.6 + }, + { + "date": "2025-09-24", + "value": 61.4 + }, + { + "date": "2025-09-30", + "value": 40.1 + }, + { + "date": "2025-10-04", + "value": 47.2 + }, + { + "date": "2025-10-10", + "value": 51.9 + }, + { + "date": "2025-10-16", + "value": 56.6 + }, + { + "date": "2025-10-22", + "value": 35.4 + }, + { + "date": "2025-10-28", + "value": 40.1 + }, + { + "date": "2025-11-05", + "value": 59.0 + }, + { + "date": "2025-11-11", + "value": 63.7 + }, + { + "date": "2025-11-17", + "value": 42.5 + }, + { + "date": "2025-11-23", + "value": 48.4 + }, + { + "date": "2025-11-29", + "value": 51.9 + }, + { + "date": "2025-12-06", + "value": 59.0 + }, + { + "date": "2025-12-12", + "value": 37.8 + }, + { + "date": "2025-12-18", + "value": 42.5 + }, + { + "date": "2025-12-24", + "value": 46.0 + }, + { + "date": "2025-12-30", + "value": 50.7 + }, + { + "date": "2026-01-04", + "value": 33.0 + }, + { + "date": "2026-01-10", + "value": 37.8 + }, + { + "date": "2026-01-16", + "value": 41.3 + }, + { + "date": "2026-01-22", + "value": 44.8 + }, + { + "date": "2026-01-28", + "value": 49.6 + }, + { + "date": "2026-02-05", + "value": 46.0 + }, + { + "date": "2026-02-11", + "value": 48.4 + }, + { + "date": "2026-02-17", + "value": 53.1 + }, + { + "date": "2026-02-23", + "value": 56.6 + }, + { + "date": "2026-02-29", + "value": 61.4 + }, + { + "date": "2026-03-06", + "value": 43.7 + }, + { + "date": "2026-03-12", + "value": 47.2 + }, + { + "date": "2026-03-18", + "value": 51.9 + }, + { + "date": "2026-03-24", + "value": 56.6 + }, + { + "date": "2026-03-30", + "value": 35.4 + }, + { + "date": "2026-04-04", + "value": 55.5 + }, + { + "date": "2026-04-10", + "value": 59.0 + }, + { + "date": "2026-04-16", + "value": 63.7 + }, + { + "date": "2026-04-22", + "value": 42.5 + }, + { + "date": "2026-04-28", + "value": 48.4 + }, + { + "date": "2026-05-05", + "value": 54.3 + }, + { + "date": "2026-05-11", + "value": 59.0 + }, + { + "date": "2026-05-17", + "value": 37.8 + }, + { + "date": "2026-05-23", + "value": 42.5 + }, + { + "date": "2026-05-29", + "value": 46.0 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 51.1, + "median": 47.2, + "p10": 30.2, + "p25": 36.6, + "p75": 63.7, + "p90": 73.6, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 60.2, + "median": 50.1, + "p10": 13.9, + "p25": 27.7, + "p75": 82.6, + "p90": 114.5, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 64.9, + "median": 73.2, + "p10": 31.6, + "p25": 47.2, + "p75": 86.7, + "p90": 94.9, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 61.4, + "median": 56.6, + "p10": 23.6, + "p25": 41.3, + "p75": 85.0, + "p90": 101.2, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 51.1, + "median": 47.2, + "p10": 22.3, + "p25": 29.3, + "p75": 69.0, + "p90": 82.8, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 52.7, + "median": 44.2, + "p10": 16.5, + "p25": 27.5, + "p75": 70.0, + "p90": 97.3, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 51.9, + "median": 53.1, + "p10": 43.4, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 46.3, + "median": 47.2, + "p10": 37.3, + "p25": 40.1, + "p75": 51.9, + "p90": 54.8, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 53.1, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 59.0, + "p90": 61.8, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 47.2, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 50.7, + "p90": 55.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 41.3, + "median": 41.3, + "p10": 34.9, + "p25": 37.8, + "p75": 44.8, + "p90": 47.7, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 53.1, + "median": 53.1, + "p10": 47.0, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 47.0, + "median": 47.2, + "p10": 38.7, + "p25": 43.7, + "p75": 51.9, + "p90": 54.8, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 53.8, + "median": 55.5, + "p10": 44.8, + "p25": 48.4, + "p75": 59.0, + "p90": 61.8, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 47.9, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 54.3, + "p90": 57.1, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": null + }, + { + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 50, + "mean": 5.2, + "median": 4.7, + "std": 2.1, + "min": 1.2, + "max": 16.5, + "p25": 3.9, + "p75": 5.9, + "p85": 5.9, + "p95": 7.8 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "cost": null, + "observations": [ + { + "date": "2022-04-18", + "value": 3.5 + }, + { + "date": "2022-07-05", + "value": 5.9 + }, + { + "date": "2022-10-12", + "value": 2.4 + }, + { + "date": "2023-01-20", + "value": 8.3 + }, + { + "date": "2023-04-15", + "value": 4.7 + }, + { + "date": "2023-07-28", + "value": 7.1 + }, + { + "date": "2023-10-05", + "value": 3.5 + }, + { + "date": "2024-01-12", + "value": 16.5 + }, + { + "date": "2024-04-22", + "value": 4.7 + }, + { + "date": "2024-07-10", + "value": 9.4 + }, + { + "date": "2024-10-18", + "value": 3.5 + }, + { + "date": "2025-01-25", + "value": 5.9 + }, + { + "date": "2025-05-08", + "value": 1.2 + }, + { + "date": "2025-08-15", + "value": 7.1 + }, + { + "date": "2025-09-04", + "value": 3.5 + }, + { + "date": "2025-09-10", + "value": 4.7 + }, + { + "date": "2025-09-16", + "value": 4.7 + }, + { + "date": "2025-09-22", + "value": 4.7 + }, + { + "date": "2025-10-05", + "value": 3.5 + }, + { + "date": "2025-10-11", + "value": 4.7 + }, + { + "date": "2025-10-17", + "value": 4.7 + }, + { + "date": "2025-10-23", + "value": 4.7 + }, + { + "date": "2025-11-06", + "value": 4.7 + }, + { + "date": "2025-11-12", + "value": 5.9 + }, + { + "date": "2025-11-18", + "value": 5.9 + }, + { + "date": "2025-11-24", + "value": 5.9 + }, + { + "date": "2025-12-04", + "value": 4.7 + }, + { + "date": "2025-12-10", + "value": 5.9 + }, + { + "date": "2025-12-16", + "value": 5.9 + }, + { + "date": "2025-12-22", + "value": 3.5 + }, + { + "date": "2026-01-05", + "value": 4.7 + }, + { + "date": "2026-01-11", + "value": 5.9 + }, + { + "date": "2026-01-17", + "value": 3.5 + }, + { + "date": "2026-01-23", + "value": 3.5 + }, + { + "date": "2026-02-06", + "value": 5.9 + }, + { + "date": "2026-02-12", + "value": 3.5 + }, + { + "date": "2026-02-18", + "value": 4.7 + }, + { + "date": "2026-02-24", + "value": 4.7 + }, + { + "date": "2026-03-04", + "value": 3.5 + }, + { + "date": "2026-03-10", + "value": 3.5 + }, + { + "date": "2026-03-16", + "value": 4.7 + }, + { + "date": "2026-03-22", + "value": 4.7 + }, + { + "date": "2026-04-05", + "value": 4.7 + }, + { + "date": "2026-04-11", + "value": 4.7 + }, + { + "date": "2026-04-17", + "value": 5.9 + }, + { + "date": "2026-04-23", + "value": 5.9 + }, + { + "date": "2026-05-06", + "value": 4.7 + }, + { + "date": "2026-05-12", + "value": 4.7 + }, + { + "date": "2026-05-18", + "value": 5.9 + }, + { + "date": "2026-05-24", + "value": 5.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-01", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2023-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 16.5, + "median": 16.5, + "p10": 16.5, + "p25": 16.5, + "p75": 16.5, + "p90": 16.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2024-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-01", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 5.7, + "median": 5.9, + "p10": 5.1, + "p25": 5.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2025-12", + "mean": 5.1, + "median": 5.3, + "p10": 3.9, + "p25": 4.5, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.5, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 5.1, + "p90": 5.5, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.7, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 5.1, + "p90": 5.5, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 5.3, + "median": 5.3, + "p10": 4.7, + "p25": 4.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2026-05", + "mean": 5.3, + "median": 5.3, + "p10": 4.7, + "p25": 4.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + } + ], + "n_batches": 50, + "n_movements": null, + "yield_summary": { + "median": 98.5, + "mean": 97.2, + "reference": 100.0, + "n": 50 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "material": "90000200001", + "plant": "PL-A", + "stats": { + "n": 73, + "mean": 20.5, + "median": 18.9, + "std": 10.6, + "min": 2.4, + "max": 64.9, + "p25": 15.3, + "p75": 22.4, + "p85": 24.1, + "p95": 43.7 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "cost": { + "unit_price": 14.75, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "observations": [ + { + "date": "2022-05-05", + "value": 14.2 + }, + { + "date": "2022-05-15", + "value": 29.5 + }, + { + "date": "2022-05-22", + "value": 9.4 + }, + { + "date": "2022-11-03", + "value": 41.3 + }, + { + "date": "2022-11-10", + "value": 17.7 + }, + { + "date": "2022-11-18", + "value": 5.9 + }, + { + "date": "2022-11-25", + "value": 26.0 + }, + { + "date": "2023-05-08", + "value": 21.2 + }, + { + "date": "2023-05-15", + "value": 47.2 + }, + { + "date": "2023-05-22", + "value": 11.8 + }, + { + "date": "2023-11-06", + "value": 64.9 + }, + { + "date": "2023-11-13", + "value": 2.4 + }, + { + "date": "2023-11-20", + "value": 33.0 + }, + { + "date": "2023-11-27", + "value": 17.7 + }, + { + "date": "2023-11-30", + "value": 9.4 + }, + { + "date": "2024-05-06", + "value": 23.6 + }, + { + "date": "2024-05-13", + "value": 53.1 + }, + { + "date": "2024-05-20", + "value": 14.2 + }, + { + "date": "2024-05-27", + "value": 3.5 + }, + { + "date": "2024-11-04", + "value": 21.2 + }, + { + "date": "2024-11-11", + "value": 35.4 + }, + { + "date": "2024-11-18", + "value": 9.4 + }, + { + "date": "2025-05-05", + "value": 26.0 + }, + { + "date": "2025-05-09", + "value": 41.3 + }, + { + "date": "2025-05-13", + "value": 5.9 + }, + { + "date": "2025-05-17", + "value": 17.7 + }, + { + "date": "2025-05-21", + "value": 49.6 + }, + { + "date": "2025-05-25", + "value": 11.8 + }, + { + "date": "2025-09-05", + "value": 16.5 + }, + { + "date": "2025-09-11", + "value": 18.9 + }, + { + "date": "2025-09-17", + "value": 20.1 + }, + { + "date": "2025-09-23", + "value": 21.2 + }, + { + "date": "2025-09-29", + "value": 22.4 + }, + { + "date": "2025-10-06", + "value": 16.5 + }, + { + "date": "2025-10-12", + "value": 17.7 + }, + { + "date": "2025-10-18", + "value": 18.9 + }, + { + "date": "2025-10-24", + "value": 21.2 + }, + { + "date": "2025-10-30", + "value": 13.0 + }, + { + "date": "2025-11-04", + "value": 21.2 + }, + { + "date": "2025-11-10", + "value": 22.4 + }, + { + "date": "2025-11-16", + "value": 23.6 + }, + { + "date": "2025-11-22", + "value": 16.5 + }, + { + "date": "2025-11-28", + "value": 17.7 + }, + { + "date": "2025-12-05", + "value": 20.1 + }, + { + "date": "2025-12-11", + "value": 22.4 + }, + { + "date": "2025-12-17", + "value": 14.2 + }, + { + "date": "2025-12-23", + "value": 16.5 + }, + { + "date": "2025-12-29", + "value": 17.7 + }, + { + "date": "2026-01-06", + "value": 20.1 + }, + { + "date": "2026-01-12", + "value": 13.0 + }, + { + "date": "2026-01-18", + "value": 14.2 + }, + { + "date": "2026-01-24", + "value": 15.3 + }, + { + "date": "2026-01-30", + "value": 16.5 + }, + { + "date": "2026-02-04", + "value": 15.3 + }, + { + "date": "2026-02-10", + "value": 16.5 + }, + { + "date": "2026-02-16", + "value": 18.9 + }, + { + "date": "2026-02-22", + "value": 20.1 + }, + { + "date": "2026-02-28", + "value": 21.2 + }, + { + "date": "2026-03-05", + "value": 15.3 + }, + { + "date": "2026-03-11", + "value": 16.5 + }, + { + "date": "2026-03-17", + "value": 17.7 + }, + { + "date": "2026-03-23", + "value": 18.9 + }, + { + "date": "2026-03-29", + "value": 21.2 + }, + { + "date": "2026-04-06", + "value": 18.9 + }, + { + "date": "2026-04-12", + "value": 21.2 + }, + { + "date": "2026-04-18", + "value": 22.4 + }, + { + "date": "2026-04-24", + "value": 23.6 + }, + { + "date": "2026-04-30", + "value": 16.5 + }, + { + "date": "2026-05-04", + "value": 18.9 + }, + { + "date": "2026-05-10", + "value": 20.1 + }, + { + "date": "2026-05-16", + "value": 22.4 + }, + { + "date": "2026-05-22", + "value": 14.2 + }, + { + "date": "2026-05-28", + "value": 16.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 17.7, + "median": 14.2, + "p10": 10.4, + "p25": 11.8, + "p75": 21.8, + "p90": 26.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 22.8, + "median": 21.8, + "p10": 9.4, + "p25": 14.8, + "p75": 29.9, + "p90": 36.7, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 26.8, + "median": 21.2, + "p10": 13.7, + "p25": 16.5, + "p75": 34.2, + "p90": 42.0, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 25.5, + "median": 17.7, + "p10": 5.2, + "p25": 9.4, + "p75": 33.0, + "p90": 52.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 23.6, + "median": 18.9, + "p10": 6.7, + "p25": 11.6, + "p75": 31.0, + "p90": 44.2, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 22.1, + "median": 21.2, + "p10": 11.8, + "p25": 15.3, + "p75": 28.3, + "p90": 32.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 25.4, + "median": 21.8, + "p10": 8.8, + "p25": 13.3, + "p75": 37.5, + "p90": 45.4, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 19.8, + "median": 20.1, + "p10": 17.5, + "p25": 18.9, + "p75": 21.2, + "p90": 21.9, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 17.5, + "median": 17.7, + "p10": 14.4, + "p25": 16.5, + "p75": 18.9, + "p90": 20.3, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 20.3, + "median": 21.2, + "p10": 17.0, + "p25": 17.7, + "p75": 22.4, + "p90": 23.1, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 18.2, + "median": 17.7, + "p10": 15.1, + "p25": 16.5, + "p75": 20.1, + "p90": 21.5, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 15.8, + "median": 15.3, + "p10": 13.5, + "p25": 14.2, + "p75": 16.5, + "p90": 18.6, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 18.4, + "median": 18.9, + "p10": 15.8, + "p25": 16.5, + "p75": 20.1, + "p90": 20.8, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 17.9, + "median": 17.7, + "p10": 15.8, + "p25": 16.5, + "p75": 18.9, + "p90": 20.3, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 20.5, + "median": 21.2, + "p10": 17.5, + "p25": 18.9, + "p75": 22.4, + "p90": 23.1, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 18.4, + "median": 18.9, + "p10": 15.1, + "p25": 16.5, + "p75": 20.1, + "p90": 21.5, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 0.9, + "mean_slack": 5.1, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 0.9 + }, + "direct": { + "binding_share": 0.9, + "mean_slack": 7.2, + "next_bottleneck_days": 27.4, + "expected_marginal_per_day": 0.9 + }, + "hub-1": { + "binding_share": 0.9, + "mean_slack": 2.0, + "next_bottleneck_days": 31.3, + "expected_marginal_per_day": 0.9 + } + } + }, + { + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 3.8, + "median": 3.5, + "std": 1.7, + "min": 0.0, + "max": 11.8, + "p25": 3.5, + "p75": 4.7, + "p85": 4.7, + "p95": 6.1 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "cost": null, + "observations": [ + { + "date": "2022-05-20", + "value": 2.4 + }, + { + "date": "2022-06-10", + "value": 3.5 + }, + { + "date": "2022-07-15", + "value": 1.2 + }, + { + "date": "2022-08-22", + "value": 4.7 + }, + { + "date": "2022-10-05", + "value": 2.4 + }, + { + "date": "2022-11-18", + "value": 5.9 + }, + { + "date": "2023-01-10", + "value": 3.5 + }, + { + "date": "2023-03-25", + "value": 8.3 + }, + { + "date": "2023-05-12", + "value": 2.4 + }, + { + "date": "2023-07-08", + "value": 4.7 + }, + { + "date": "2023-09-15", + "value": 1.2 + }, + { + "date": "2023-11-22", + "value": 3.5 + }, + { + "date": "2024-01-18", + "value": 11.8 + }, + { + "date": "2024-03-08", + "value": 3.5 + }, + { + "date": "2024-05-15", + "value": 2.4 + }, + { + "date": "2024-07-22", + "value": 5.9 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 4.7 + }, + { + "date": "2025-01-15", + "value": 3.5 + }, + { + "date": "2025-03-20", + "value": 2.4 + }, + { + "date": "2025-05-28", + "value": 7.1 + }, + { + "date": "2025-08-05", + "value": 3.5 + }, + { + "date": "2025-09-05", + "value": 4.7 + }, + { + "date": "2025-09-11", + "value": 4.7 + }, + { + "date": "2025-09-17", + "value": 3.5 + }, + { + "date": "2025-09-23", + "value": 3.5 + }, + { + "date": "2025-10-06", + "value": 4.7 + }, + { + "date": "2025-10-12", + "value": 2.4 + }, + { + "date": "2025-10-18", + "value": 3.5 + }, + { + "date": "2025-10-24", + "value": 3.5 + }, + { + "date": "2025-11-04", + "value": 2.4 + }, + { + "date": "2025-11-10", + "value": 2.4 + }, + { + "date": "2025-11-16", + "value": 3.5 + }, + { + "date": "2025-11-22", + "value": 3.5 + }, + { + "date": "2025-12-05", + "value": 3.5 + }, + { + "date": "2025-12-11", + "value": 3.5 + }, + { + "date": "2025-12-17", + "value": 3.5 + }, + { + "date": "2025-12-23", + "value": 4.7 + }, + { + "date": "2026-01-06", + "value": 3.5 + }, + { + "date": "2026-01-12", + "value": 3.5 + }, + { + "date": "2026-01-18", + "value": 3.5 + }, + { + "date": "2026-01-24", + "value": 4.7 + }, + { + "date": "2026-02-04", + "value": 4.7 + }, + { + "date": "2026-02-10", + "value": 4.7 + }, + { + "date": "2026-02-16", + "value": 4.7 + }, + { + "date": "2026-02-22", + "value": 3.5 + }, + { + "date": "2026-03-05", + "value": 3.5 + }, + { + "date": "2026-03-11", + "value": 4.7 + }, + { + "date": "2026-03-17", + "value": 2.4 + }, + { + "date": "2026-03-23", + "value": 3.5 + }, + { + "date": "2026-04-06", + "value": 3.5 + }, + { + "date": "2026-04-12", + "value": 2.4 + }, + { + "date": "2026-04-18", + "value": 2.4 + }, + { + "date": "2026-04-24", + "value": 3.5 + }, + { + "date": "2026-05-04", + "value": 3.5 + }, + { + "date": "2026-05-10", + "value": 3.5 + }, + { + "date": "2026-05-16", + "value": 3.5 + }, + { + "date": "2026-05-22", + "value": 3.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-06", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2022-08", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-11", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1 + }, + { + "month": "2024-03", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2025-05", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.9, + "median": 2.9, + "p10": 2.4, + "p25": 2.4, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.9, + "median": 2.9, + "p10": 2.4, + "p25": 2.4, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + } + ], + "n_batches": 58, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": { + "median_variance": 2.1, + "mean_variance": 3.4, + "n_components": 3, + "n": 58 + }, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 3.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 4.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 58, + "mean": 4.0, + "median": 3.5, + "std": 2.1, + "min": 0.0, + "max": 15.3, + "p25": 3.5, + "p75": 4.7, + "p85": 4.7, + "p95": 7.3 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "cost": null, + "observations": [ + { + "date": "2022-05-22", + "value": 2.4 + }, + { + "date": "2022-06-13", + "value": 1.2 + }, + { + "date": "2022-07-16", + "value": 3.5 + }, + { + "date": "2022-08-26", + "value": 2.4 + }, + { + "date": "2022-10-07", + "value": 5.9 + }, + { + "date": "2022-11-23", + "value": 2.4 + }, + { + "date": "2023-01-13", + "value": 4.7 + }, + { + "date": "2023-04-01", + "value": 3.5 + }, + { + "date": "2023-05-14", + "value": 7.1 + }, + { + "date": "2023-07-12", + "value": 2.4 + }, + { + "date": "2023-09-16", + "value": 15.3 + }, + { + "date": "2023-11-25", + "value": 3.5 + }, + { + "date": "2024-01-28", + "value": 8.3 + }, + { + "date": "2024-03-11", + "value": 1.2 + }, + { + "date": "2024-05-17", + "value": 4.7 + }, + { + "date": "2024-07-27", + "value": 5.9 + }, + { + "date": "2024-09-10", + "value": 2.4 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 3.5 + }, + { + "date": "2025-03-22", + "value": 9.4 + }, + { + "date": "2025-06-03", + "value": 2.4 + }, + { + "date": "2025-08-08", + "value": 5.9 + }, + { + "date": "2025-09-04", + "value": 2.4 + }, + { + "date": "2025-09-10", + "value": 3.5 + }, + { + "date": "2025-09-16", + "value": 3.5 + }, + { + "date": "2025-09-22", + "value": 3.5 + }, + { + "date": "2025-10-05", + "value": 3.5 + }, + { + "date": "2025-10-11", + "value": 3.5 + }, + { + "date": "2025-10-17", + "value": 4.7 + }, + { + "date": "2025-10-23", + "value": 4.7 + }, + { + "date": "2025-11-06", + "value": 3.5 + }, + { + "date": "2025-11-12", + "value": 3.5 + }, + { + "date": "2025-11-18", + "value": 3.5 + }, + { + "date": "2025-11-24", + "value": 4.7 + }, + { + "date": "2025-12-04", + "value": 3.5 + }, + { + "date": "2025-12-10", + "value": 3.5 + }, + { + "date": "2025-12-16", + "value": 3.5 + }, + { + "date": "2025-12-22", + "value": 2.4 + }, + { + "date": "2026-01-05", + "value": 4.7 + }, + { + "date": "2026-01-11", + "value": 4.7 + }, + { + "date": "2026-01-17", + "value": 3.5 + }, + { + "date": "2026-01-23", + "value": 3.5 + }, + { + "date": "2026-02-06", + "value": 4.7 + }, + { + "date": "2026-02-12", + "value": 2.4 + }, + { + "date": "2026-02-18", + "value": 3.5 + }, + { + "date": "2026-02-24", + "value": 3.5 + }, + { + "date": "2026-03-04", + "value": 3.5 + }, + { + "date": "2026-03-10", + "value": 3.5 + }, + { + "date": "2026-03-16", + "value": 3.5 + }, + { + "date": "2026-03-22", + "value": 4.7 + }, + { + "date": "2026-04-05", + "value": 3.5 + }, + { + "date": "2026-04-11", + "value": 3.5 + }, + { + "date": "2026-04-17", + "value": 3.5 + }, + { + "date": "2026-04-23", + "value": 3.5 + }, + { + "date": "2026-05-06", + "value": 3.5 + }, + { + "date": "2026-05-12", + "value": 3.5 + }, + { + "date": "2026-05-18", + "value": 3.5 + }, + { + "date": "2026-05-24", + "value": 3.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-10", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-09", + "mean": 15.3, + "median": 15.3, + "p10": 15.3, + "p25": 15.3, + "p75": 15.3, + "p90": 15.3, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.3, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.3, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": { + "median": 99.2, + "mean": 98.5, + "reference": 100.0, + "n": 58 + }, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 7.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 6.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "material": "90000300001", + "plant": "PL-A", + "stats": { + "n": 57, + "mean": 15.0, + "median": 14.2, + "std": 6.6, + "min": 2.4, + "max": 49.6, + "p25": 11.8, + "p75": 16.5, + "p85": 17.7, + "p95": 24.1 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 33.63, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "observations": [ + { + "date": "2023-03-10", + "value": 9.4 + }, + { + "date": "2023-03-25", + "value": 26.0 + }, + { + "date": "2023-09-20", + "value": 49.6 + }, + { + "date": "2024-03-15", + "value": 7.1 + }, + { + "date": "2024-03-28", + "value": 21.2 + }, + { + "date": "2024-09-05", + "value": 33.0 + }, + { + "date": "2024-09-15", + "value": 14.2 + }, + { + "date": "2024-09-25", + "value": 2.4 + }, + { + "date": "2025-03-10", + "value": 17.7 + }, + { + "date": "2025-03-22", + "value": 5.9 + }, + { + "date": "2025-07-08", + "value": 23.6 + }, + { + "date": "2025-07-22", + "value": 4.7 + }, + { + "date": "2025-09-05", + "value": 16.5 + }, + { + "date": "2025-09-11", + "value": 17.7 + }, + { + "date": "2025-09-17", + "value": 11.8 + }, + { + "date": "2025-09-23", + "value": 13.0 + }, + { + "date": "2025-09-29", + "value": 14.2 + }, + { + "date": "2025-10-06", + "value": 16.5 + }, + { + "date": "2025-10-12", + "value": 9.4 + }, + { + "date": "2025-10-18", + "value": 11.8 + }, + { + "date": "2025-10-24", + "value": 13.0 + }, + { + "date": "2025-10-30", + "value": 13.0 + }, + { + "date": "2025-11-04", + "value": 11.8 + }, + { + "date": "2025-11-10", + "value": 14.2 + }, + { + "date": "2025-11-16", + "value": 14.2 + }, + { + "date": "2025-11-22", + "value": 15.3 + }, + { + "date": "2025-11-28", + "value": 16.5 + }, + { + "date": "2025-12-05", + "value": 11.8 + }, + { + "date": "2025-12-11", + "value": 13.0 + }, + { + "date": "2025-12-17", + "value": 14.2 + }, + { + "date": "2025-12-23", + "value": 15.3 + }, + { + "date": "2025-12-29", + "value": 16.5 + }, + { + "date": "2026-01-06", + "value": 15.3 + }, + { + "date": "2026-01-12", + "value": 16.5 + }, + { + "date": "2026-01-18", + "value": 17.7 + }, + { + "date": "2026-01-24", + "value": 18.9 + }, + { + "date": "2026-01-30", + "value": 13.0 + }, + { + "date": "2026-02-04", + "value": 15.3 + }, + { + "date": "2026-02-10", + "value": 16.5 + }, + { + "date": "2026-02-16", + "value": 17.7 + }, + { + "date": "2026-02-22", + "value": 11.8 + }, + { + "date": "2026-02-28", + "value": 13.0 + }, + { + "date": "2026-03-05", + "value": 15.3 + }, + { + "date": "2026-03-11", + "value": 16.5 + }, + { + "date": "2026-03-17", + "value": 9.4 + }, + { + "date": "2026-03-23", + "value": 11.8 + }, + { + "date": "2026-03-29", + "value": 13.0 + }, + { + "date": "2026-04-06", + "value": 18.9 + }, + { + "date": "2026-04-12", + "value": 11.8 + }, + { + "date": "2026-04-18", + "value": 14.2 + }, + { + "date": "2026-04-24", + "value": 14.2 + }, + { + "date": "2026-04-30", + "value": 15.3 + }, + { + "date": "2026-05-04", + "value": 10.6 + }, + { + "date": "2026-05-10", + "value": 11.8 + }, + { + "date": "2026-05-16", + "value": 13.0 + }, + { + "date": "2026-05-22", + "value": 14.2 + }, + { + "date": "2026-05-28", + "value": 15.3 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 17.7, + "median": 17.7, + "p10": 11.1, + "p25": 13.6, + "p75": 21.8, + "p90": 24.3, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 14.2, + "median": 14.2, + "p10": 8.5, + "p25": 10.6, + "p75": 17.7, + "p90": 19.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 16.5, + "median": 14.2, + "p10": 4.7, + "p25": 8.3, + "p75": 23.6, + "p90": 29.3, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 11.8, + "median": 11.8, + "p10": 7.1, + "p25": 8.8, + "p75": 14.8, + "p90": 16.5, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 14.2, + "median": 14.2, + "p10": 6.6, + "p25": 9.4, + "p75": 18.9, + "p90": 21.7, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 14.6, + "median": 14.2, + "p10": 12.3, + "p25": 13.0, + "p75": 16.5, + "p90": 17.2, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 12.7, + "median": 13.0, + "p10": 10.4, + "p25": 11.8, + "p75": 13.0, + "p90": 15.1, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 14.4, + "median": 14.2, + "p10": 12.7, + "p25": 14.2, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 14.2, + "median": 14.2, + "p10": 12.3, + "p25": 13.0, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 16.3, + "median": 16.5, + "p10": 13.9, + "p25": 15.3, + "p75": 17.7, + "p90": 18.4, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 14.9, + "median": 15.3, + "p10": 12.3, + "p25": 13.0, + "p75": 16.5, + "p90": 17.2, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 13.2, + "median": 13.0, + "p10": 10.4, + "p25": 11.8, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 14.9, + "median": 14.2, + "p10": 12.7, + "p25": 14.2, + "p75": 15.3, + "p90": 17.5, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 13.0, + "median": 13.0, + "p10": 11.1, + "p25": 11.8, + "p75": 14.2, + "p90": 14.9, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 12.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "direct_ship_pla", + "label": "Direct-to-Customer Ship", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192Customer", + "stats": { + "n": 35, + "mean": 24.7, + "median": 24.8, + "std": 5.4, + "min": 14.2, + "max": 44.8, + "p25": 21.8, + "p75": 27.1, + "p85": 29.4, + "p95": 31.4 + }, + "plifz": null, + "plifz_note": "No planning parameter set", + "pct_exceeding_plifz": null, + "cost": null, + "observations": [ + { + "date": "2023-04-05", + "value": 21.2 + }, + { + "date": "2023-10-12", + "value": 29.5 + }, + { + "date": "2024-04-08", + "value": 14.2 + }, + { + "date": "2024-09-20", + "value": 44.8 + }, + { + "date": "2024-10-15", + "value": 23.6 + }, + { + "date": "2025-03-25", + "value": 17.7 + }, + { + "date": "2025-04-10", + "value": 33.0 + }, + { + "date": "2025-07-30", + "value": 28.3 + }, + { + "date": "2025-09-04", + "value": 20.1 + }, + { + "date": "2025-09-10", + "value": 22.4 + }, + { + "date": "2025-09-16", + "value": 24.8 + }, + { + "date": "2025-10-05", + "value": 20.1 + }, + { + "date": "2025-10-11", + "value": 22.4 + }, + { + "date": "2025-10-17", + "value": 23.6 + }, + { + "date": "2025-11-06", + "value": 26.0 + }, + { + "date": "2025-11-12", + "value": 27.1 + }, + { + "date": "2025-11-18", + "value": 29.5 + }, + { + "date": "2025-12-04", + "value": 24.8 + }, + { + "date": "2025-12-10", + "value": 27.1 + }, + { + "date": "2025-12-16", + "value": 29.5 + }, + { + "date": "2026-01-05", + "value": 24.8 + }, + { + "date": "2026-01-11", + "value": 27.1 + }, + { + "date": "2026-01-17", + "value": 16.5 + }, + { + "date": "2026-02-06", + "value": 30.7 + }, + { + "date": "2026-02-12", + "value": 20.1 + }, + { + "date": "2026-02-18", + "value": 22.4 + }, + { + "date": "2026-03-04", + "value": 17.7 + }, + { + "date": "2026-03-10", + "value": 20.1 + }, + { + "date": "2026-03-16", + "value": 22.4 + }, + { + "date": "2026-04-05", + "value": 23.6 + }, + { + "date": "2026-04-11", + "value": 26.0 + }, + { + "date": "2026-04-17", + "value": 27.1 + }, + { + "date": "2026-05-06", + "value": 23.6 + }, + { + "date": "2026-05-12", + "value": 24.8 + }, + { + "date": "2026-05-18", + "value": 27.1 + } + ], + "monthly": [ + { + "month": "2023-04", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2023-10", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2024-09", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 23.6, + "median": 23.6, + "p10": 23.6, + "p25": 23.6, + "p75": 23.6, + "p90": 23.6, + "n": 1 + }, + { + "month": "2025-03", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2025-04", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-07", + "mean": 28.3, + "median": 28.3, + "p10": 28.3, + "p25": 28.3, + "p75": 28.3, + "p90": 28.3, + "n": 1 + }, + { + "month": "2025-09", + "mean": 22.4, + "median": 22.4, + "p10": 20.5, + "p25": 21.2, + "p75": 23.6, + "p90": 24.3, + "n": 3 + }, + { + "month": "2025-10", + "mean": 22.1, + "median": 22.4, + "p10": 20.5, + "p25": 21.2, + "p75": 23.0, + "p90": 23.4, + "n": 3 + }, + { + "month": "2025-11", + "mean": 27.5, + "median": 27.1, + "p10": 26.2, + "p25": 26.5, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2025-12", + "mean": 27.1, + "median": 27.1, + "p10": 25.3, + "p25": 26.0, + "p75": 28.3, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-01", + "mean": 22.8, + "median": 24.8, + "p10": 18.2, + "p25": 20.6, + "p75": 26.0, + "p90": 26.7, + "n": 3 + }, + { + "month": "2026-02", + "mean": 24.4, + "median": 22.4, + "p10": 20.5, + "p25": 21.2, + "p75": 26.5, + "p90": 29.0, + "n": 3 + }, + { + "month": "2026-03", + "mean": 20.1, + "median": 20.1, + "p10": 18.2, + "p25": 18.9, + "p75": 21.2, + "p90": 21.9, + "n": 3 + }, + { + "month": "2026-04", + "mean": 25.6, + "median": 26.0, + "p10": 24.1, + "p25": 24.8, + "p75": 26.5, + "p90": 26.9, + "n": 3 + }, + { + "month": "2026-05", + "mean": 25.1, + "median": 24.8, + "p10": 23.8, + "p25": 24.2, + "p75": 26.0, + "p90": 26.7, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + }, + "direct": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 22.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "material": "90000300001", + "plant": "PL-A\u2192HUB-1", + "stats": { + "n": 42, + "mean": 36.9, + "median": 36.0, + "std": 8.4, + "min": 17.7, + "max": 64.9, + "p25": 31.9, + "p75": 42.5, + "p85": 44.8, + "p95": 49.4 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "cost": null, + "observations": [ + { + "date": "2022-07-20", + "value": 33.0 + }, + { + "date": "2022-11-30", + "value": 41.3 + }, + { + "date": "2023-03-15", + "value": 26.0 + }, + { + "date": "2023-07-10", + "value": 49.6 + }, + { + "date": "2023-10-25", + "value": 35.4 + }, + { + "date": "2024-02-08", + "value": 64.9 + }, + { + "date": "2024-05-20", + "value": 29.5 + }, + { + "date": "2024-08-12", + "value": 44.8 + }, + { + "date": "2024-11-05", + "value": 17.7 + }, + { + "date": "2025-01-22", + "value": 37.8 + }, + { + "date": "2025-04-10", + "value": 33.0 + }, + { + "date": "2025-06-18", + "value": 53.1 + }, + { + "date": "2025-07-15", + "value": 35.4 + }, + { + "date": "2025-08-05", + "value": 26.0 + }, + { + "date": "2025-09-05", + "value": 42.5 + }, + { + "date": "2025-09-10", + "value": 44.8 + }, + { + "date": "2025-09-11", + "value": 46.0 + }, + { + "date": "2025-09-17", + "value": 30.7 + }, + { + "date": "2025-10-06", + "value": 42.5 + }, + { + "date": "2025-10-12", + "value": 27.1 + }, + { + "date": "2025-10-18", + "value": 30.7 + }, + { + "date": "2025-11-04", + "value": 31.9 + }, + { + "date": "2025-11-10", + "value": 36.6 + }, + { + "date": "2025-11-16", + "value": 38.9 + }, + { + "date": "2025-12-05", + "value": 31.9 + }, + { + "date": "2025-12-11", + "value": 34.2 + }, + { + "date": "2025-12-17", + "value": 37.8 + }, + { + "date": "2026-01-06", + "value": 30.7 + }, + { + "date": "2026-01-12", + "value": 34.2 + }, + { + "date": "2026-01-18", + "value": 36.6 + }, + { + "date": "2026-02-04", + "value": 38.9 + }, + { + "date": "2026-02-10", + "value": 42.5 + }, + { + "date": "2026-02-16", + "value": 46.0 + }, + { + "date": "2026-03-05", + "value": 38.9 + }, + { + "date": "2026-03-11", + "value": 42.5 + }, + { + "date": "2026-03-17", + "value": 27.1 + }, + { + "date": "2026-04-06", + "value": 47.2 + }, + { + "date": "2026-04-12", + "value": 31.9 + }, + { + "date": "2026-04-18", + "value": 36.6 + }, + { + "date": "2026-05-04", + "value": 28.3 + }, + { + "date": "2026-05-10", + "value": 31.9 + }, + { + "date": "2026-05-16", + "value": 34.2 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2023-03", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1 + }, + { + "month": "2023-10", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2024-02", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2024-05", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-11", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-04", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 53.1, + "median": 53.1, + "p10": 53.1, + "p25": 53.1, + "p75": 53.1, + "p90": 53.1, + "n": 1 + }, + { + "month": "2025-07", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 41.1, + "median": 43.7, + "p10": 34.2, + "p25": 39.5, + "p75": 45.2, + "p90": 45.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 33.4, + "median": 30.7, + "p10": 27.8, + "p25": 28.9, + "p75": 36.6, + "p90": 40.1, + "n": 3 + }, + { + "month": "2025-11", + "mean": 35.8, + "median": 36.6, + "p10": 32.8, + "p25": 34.2, + "p75": 37.8, + "p90": 38.5, + "n": 3 + }, + { + "month": "2025-12", + "mean": 34.6, + "median": 34.2, + "p10": 32.3, + "p25": 33.0, + "p75": 36.0, + "p90": 37.1, + "n": 3 + }, + { + "month": "2026-01", + "mean": 33.9, + "median": 34.2, + "p10": 31.4, + "p25": 32.4, + "p75": 35.4, + "p90": 36.1, + "n": 3 + }, + { + "month": "2026-02", + "mean": 42.5, + "median": 42.5, + "p10": 39.6, + "p25": 40.7, + "p75": 44.2, + "p90": 45.3, + "n": 3 + }, + { + "month": "2026-03", + "mean": 36.2, + "median": 38.9, + "p10": 29.5, + "p25": 33.0, + "p75": 40.7, + "p90": 41.8, + "n": 3 + }, + { + "month": "2026-04", + "mean": 38.6, + "median": 36.6, + "p10": 32.8, + "p25": 34.2, + "p75": 41.9, + "p90": 45.1, + "n": 3 + }, + { + "month": "2026-05", + "mean": 31.5, + "median": 31.9, + "p10": 29.0, + "p25": 30.1, + "p75": 33.0, + "p90": 33.7, + "n": 3 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 29.0, + "expected_marginal_per_day": 1.0 + } + } + }, + { + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "material": "90000300001", + "plant": "HUB-1", + "stats": { + "n": 37, + "mean": 53.1, + "median": 51.9, + "std": 16.5, + "min": 11.8, + "max": 112.1, + "p25": 42.5, + "p75": 57.8, + "p85": 62.5, + "p95": 79.8 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "cost": { + "unit_price": 33.63, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "observations": [ + { + "date": "2022-09-15", + "value": 49.6 + }, + { + "date": "2023-05-05", + "value": 76.7 + }, + { + "date": "2023-05-20", + "value": 33.0 + }, + { + "date": "2024-01-10", + "value": 112.1 + }, + { + "date": "2024-01-25", + "value": 41.3 + }, + { + "date": "2024-08-15", + "value": 11.8 + }, + { + "date": "2025-02-05", + "value": 92.0 + }, + { + "date": "2025-02-18", + "value": 64.9 + }, + { + "date": "2025-08-10", + "value": 49.6 + }, + { + "date": "2025-08-20", + "value": 37.8 + }, + { + "date": "2025-09-06", + "value": 46.0 + }, + { + "date": "2025-09-12", + "value": 49.6 + }, + { + "date": "2025-09-18", + "value": 54.3 + }, + { + "date": "2025-10-04", + "value": 57.8 + }, + { + "date": "2025-10-10", + "value": 62.5 + }, + { + "date": "2025-10-16", + "value": 67.3 + }, + { + "date": "2025-11-05", + "value": 56.6 + }, + { + "date": "2025-11-11", + "value": 61.4 + }, + { + "date": "2025-11-17", + "value": 40.1 + }, + { + "date": "2025-12-06", + "value": 56.6 + }, + { + "date": "2025-12-12", + "value": 35.4 + }, + { + "date": "2025-12-18", + "value": 40.1 + }, + { + "date": "2026-01-04", + "value": 42.5 + }, + { + "date": "2026-01-10", + "value": 48.4 + }, + { + "date": "2026-01-16", + "value": 50.7 + }, + { + "date": "2026-02-05", + "value": 42.5 + }, + { + "date": "2026-02-11", + "value": 46.0 + }, + { + "date": "2026-02-17", + "value": 49.6 + }, + { + "date": "2026-03-06", + "value": 54.3 + }, + { + "date": "2026-03-12", + "value": 57.8 + }, + { + "date": "2026-03-18", + "value": 62.5 + }, + { + "date": "2026-04-04", + "value": 53.1 + }, + { + "date": "2026-04-10", + "value": 56.6 + }, + { + "date": "2026-04-16", + "value": 61.4 + }, + { + "date": "2026-05-05", + "value": 51.9 + }, + { + "date": "2026-05-11", + "value": 56.6 + }, + { + "date": "2026-05-17", + "value": 35.4 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 54.9, + "median": 54.9, + "p10": 37.4, + "p25": 44.0, + "p75": 65.8, + "p90": 72.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 76.7, + "median": 76.7, + "p10": 48.4, + "p25": 59.0, + "p75": 94.4, + "p90": 105.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 78.5, + "median": 78.5, + "p10": 67.6, + "p25": 71.7, + "p75": 85.3, + "p90": 89.3, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 43.7, + "median": 43.7, + "p10": 38.9, + "p25": 40.7, + "p75": 46.6, + "p90": 48.4, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 49.9, + "median": 49.6, + "p10": 46.7, + "p25": 47.8, + "p75": 51.9, + "p90": 53.3, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 62.5, + "median": 62.5, + "p10": 58.8, + "p25": 60.2, + "p75": 64.9, + "p90": 66.3, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 52.7, + "median": 56.6, + "p10": 43.4, + "p25": 48.4, + "p75": 59.0, + "p90": 60.4, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 44.0, + "median": 40.1, + "p10": 36.3, + "p25": 37.8, + "p75": 48.4, + "p90": 53.3, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 47.2, + "median": 48.4, + "p10": 43.7, + "p25": 45.4, + "p75": 49.6, + "p90": 50.3, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 46.0, + "median": 46.0, + "p10": 43.2, + "p25": 44.2, + "p75": 47.8, + "p90": 48.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 58.2, + "median": 57.8, + "p10": 55.0, + "p25": 56.0, + "p75": 60.2, + "p90": 61.6, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 57.0, + "median": 56.6, + "p10": 53.8, + "p25": 54.9, + "p75": 59.0, + "p90": 60.4, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 48.0, + "median": 51.9, + "p10": 38.7, + "p25": 43.7, + "p75": 54.3, + "p90": 55.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "n_batches": null, + "n_movements": null, + "yield_summary": null, + "consumption_summary": null, + "binding": { + "all": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + }, + "hub-1": { + "binding_share": 1.0, + "mean_slack": null, + "next_bottleneck_days": 45.0, + "expected_marginal_per_day": 1.0 + } + } + } + ], + "edges": [ + { + "source": "procurement_highland_arabica", + "target": "raw_dwell_highland_arabica", + "label": "101" + }, + { + "source": "procurement_lowland_robusta", + "target": "raw_dwell_lowland_robusta", + "label": "101" + }, + { + "source": "procurement_washed_bourbon", + "target": "raw_dwell_washed_bourbon", + "label": "101" + }, + { + "source": "raw_dwell_highland_arabica", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "raw_dwell_lowland_robusta", + "target": "prod_duration_green_blend", + "label": "261" + }, + { + "source": "prod_duration_green_blend", + "target": "intermed_dwell_green_blend", + "label": "101" + }, + { + "source": "raw_dwell_washed_bourbon", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "intermed_dwell_green_blend", + "target": "prod_duration_harbor_dark_roast", + "label": "261" + }, + { + "source": "prod_duration_harbor_dark_roast", + "target": "prod_to_qa_pla", + "label": "101" + }, + { + "source": "post_qa_ship_pla", + "target": "direct_ship_pla", + "label": "601" + }, + { + "source": "post_qa_ship_pla", + "target": "transit_pla_hub1", + "label": "641" + }, + { + "source": "transit_pla_hub1", + "target": "dest_dwell_hub1" + }, + { + "source": "prod_to_qa_pla", + "target": "post_qa_ship_pla" + } + ], + "pipeline_summary": { + "direct": { + "label": "Direct to customer", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 29.9, + "median": 30, + "pct_of_total": 17.6, + "n": 60 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 99.8, + "median": 101, + "pct_of_total": 58.9, + "n": 60 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.6, + "median": 7, + "pct_of_total": 3.9, + "n": 60 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 33.2, + "median": 33, + "pct_of_total": 19.6, + "n": 60 + } + ], + "total_mean": 169.5, + "total_median": 171 + }, + "hub-1": { + "label": "HUB-1", + "stages": [ + { + "id": "seg_proc_to_prodstart", + "label": "Procurement \u2192 Production Start", + "type": "procurement", + "mean": 28.4, + "median": 29, + "pct_of_total": 12.8, + "n": 40 + }, + { + "id": "seg_prodstart_to_prodfinish", + "label": "Production Start \u2192 Production Finish", + "type": "production", + "mean": 102.1, + "median": 104, + "pct_of_total": 46.1, + "n": 40 + }, + { + "id": "seg_prodfinish_to_qa", + "label": "Production Finish \u2192 QA Release", + "type": "qa_hold", + "mean": 6.2, + "median": 6, + "pct_of_total": 2.8, + "n": 40 + }, + { + "id": "seg_qa_to_customer", + "label": "QA Release \u2192 Customer", + "type": "transit", + "mean": 84.8, + "median": 88, + "pct_of_total": 38.3, + "n": 40 + } + ], + "total_mean": 221.5, + "total_median": 227 + } + }, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica", + "step_ids": ["procurement_highland_arabica", "raw_dwell_highland_arabica"] + }, + { + "date": "2024-01-15", + "label": "QA process revision", + "step_ids": ["qa_hold_pla"] + } + ], + "batch_timelines": { + "batches": [ + { + "batch": "BATCH-007069", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-05-27", + "earliest_gr_date": "2024-05-29", + "earliest_production_start": "2024-07-03", + "fg_receipt_date": "2024-10-28", + "qa_release_date": "2024-11-03", + "ship_date": null, + "delivery_date": "2024-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 117, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 112, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 23 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-767678", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-13", + "earliest_gr_date": "2024-07-15", + "earliest_production_start": "2024-07-29", + "fg_receipt_date": "2024-11-05", + "qa_release_date": "2024-11-09", + "ship_date": null, + "delivery_date": "2024-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 99, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 36, + "total_days": 155, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 14, + "direct_ship_pla": 22 + } + }, + "total_from_po": 155 + }, + { + "batch": "BATCH-872783", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-25", + "earliest_gr_date": "2024-07-27", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-08", + "qa_release_date": "2024-11-15", + "ship_date": null, + "delivery_date": "2024-12-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 81, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 35, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 58, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 78, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 25 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-868247", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-20", + "earliest_gr_date": "2024-07-22", + "earliest_production_start": "2024-08-24", + "fg_receipt_date": "2024-11-10", + "qa_release_date": "2024-11-19", + "ship_date": null, + "delivery_date": "2024-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 37, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 61, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "direct_ship_pla": 20 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-775611", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-22", + "earliest_gr_date": "2024-07-24", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-11-22", + "qa_release_date": "2024-11-30", + "ship_date": null, + "delivery_date": "2024-12-31", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 95, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-544789", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-08", + "earliest_gr_date": "2024-07-10", + "earliest_production_start": "2024-08-05", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-12", + "ship_date": null, + "delivery_date": "2025-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 122, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 94, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 7, + "direct_ship_pla": 18 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-447665", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-14", + "earliest_gr_date": "2024-07-16", + "earliest_production_start": "2024-08-19", + "fg_receipt_date": "2024-12-05", + "qa_release_date": "2024-12-11", + "ship_date": null, + "delivery_date": "2025-01-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 31, + "total_days": 181, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 24, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 24, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "direct_ship_pla": 18 + } + }, + "total_from_po": 181 + }, + { + "batch": "BATCH-963613", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-26", + "fg_receipt_date": "2024-12-12", + "qa_release_date": "2024-12-19", + "ship_date": null, + "delivery_date": "2025-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 19 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-863299", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-05", + "earliest_gr_date": "2024-08-07", + "earliest_production_start": "2024-08-30", + "fg_receipt_date": "2024-12-21", + "qa_release_date": "2024-12-27", + "ship_date": null, + "delivery_date": "2025-01-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 26, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-528145", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-22", + "earliest_gr_date": "2024-08-24", + "earliest_production_start": "2024-09-11", + "fg_receipt_date": "2024-12-24", + "qa_release_date": "2024-12-30", + "ship_date": null, + "delivery_date": "2025-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 29, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 90, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 102, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 17 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-242499", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-17", + "earliest_gr_date": "2024-08-19", + "earliest_production_start": "2024-09-16", + "fg_receipt_date": "2024-12-26", + "qa_release_date": "2024-12-31", + "ship_date": null, + "delivery_date": "2025-02-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 33, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-576635", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-29", + "earliest_gr_date": "2024-10-01", + "earliest_production_start": "2024-10-26", + "fg_receipt_date": "2024-12-31", + "qa_release_date": "2025-01-07", + "ship_date": null, + "delivery_date": "2025-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 66, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 32, + "total_days": 132, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 47, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 64, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 24 + } + }, + "total_from_po": 132 + }, + { + "batch": "BATCH-221460", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-07-24", + "earliest_gr_date": "2024-07-26", + "earliest_production_start": "2024-08-28", + "fg_receipt_date": "2025-01-01", + "qa_release_date": "2025-01-08", + "ship_date": null, + "delivery_date": "2025-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 126, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 36, + "total_days": 204, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 120, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 78, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 23 + } + }, + "total_from_po": 204 + }, + { + "batch": "BATCH-666578", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-06", + "fg_receipt_date": "2025-01-10", + "qa_release_date": "2025-01-18", + "ship_date": null, + "delivery_date": "2025-02-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-208118", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-19", + "fg_receipt_date": "2025-01-11", + "qa_release_date": "2025-01-19", + "ship_date": null, + "delivery_date": "2025-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 44, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 36, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 51, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 67, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 7, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 38, + "production_days": 7, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 15, + "direct_ship_pla": 21 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-458243", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-05", + "earliest_gr_date": "2024-09-07", + "earliest_production_start": "2024-10-04", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-29", + "ship_date": null, + "delivery_date": "2025-03-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-207730", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-16", + "earliest_gr_date": "2024-09-18", + "earliest_production_start": "2024-10-14", + "fg_receipt_date": "2025-01-18", + "qa_release_date": "2025-01-22", + "ship_date": null, + "delivery_date": "2025-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 44, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 92, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 68, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 16, + "direct_ship_pla": 28 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-033995", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-08-27", + "earliest_gr_date": "2024-08-29", + "earliest_production_start": "2024-09-30", + "fg_receipt_date": "2025-01-22", + "qa_release_date": "2025-01-30", + "ship_date": null, + "delivery_date": "2025-03-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 114, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 18, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 17, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-559161", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-10", + "earliest_gr_date": "2024-09-12", + "earliest_production_start": "2024-10-16", + "fg_receipt_date": "2025-02-14", + "qa_release_date": "2025-02-19", + "ship_date": null, + "delivery_date": "2025-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 27, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 99, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 10, + "direct_ship_pla": 17 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-043249", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-28", + "earliest_gr_date": "2024-09-30", + "earliest_production_start": "2024-10-27", + "fg_receipt_date": "2025-02-12", + "qa_release_date": "2025-02-15", + "ship_date": null, + "delivery_date": "2025-03-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 108, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 36, + "total_days": 176, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 12, + "direct_ship_pla": 24 + } + }, + "total_from_po": 176 + }, + { + "batch": "BATCH-876661", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-05", + "earliest_gr_date": "2024-10-07", + "earliest_production_start": "2024-11-06", + "fg_receipt_date": "2025-02-04", + "qa_release_date": "2025-02-11", + "ship_date": null, + "delivery_date": "2025-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 31 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-758211", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-09-24", + "earliest_gr_date": "2024-09-26", + "earliest_production_start": "2024-10-24", + "fg_receipt_date": "2025-02-22", + "qa_release_date": "2025-03-01", + "ship_date": null, + "delivery_date": "2025-04-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 191, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 117, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 191 + }, + { + "batch": "BATCH-198568", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-07", + "earliest_gr_date": "2024-10-09", + "earliest_production_start": "2024-10-29", + "fg_receipt_date": "2025-02-21", + "qa_release_date": "2025-03-02", + "ship_date": null, + "delivery_date": "2025-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 115, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 38, + "total_days": 184, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 13, + "direct_ship_pla": 25 + } + }, + "total_from_po": 184 + }, + { + "batch": "BATCH-499114", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-20", + "earliest_gr_date": "2024-11-22", + "earliest_production_start": "2024-12-17", + "fg_receipt_date": "2025-03-05", + "qa_release_date": "2025-03-14", + "ship_date": null, + "delivery_date": "2025-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 78, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 31, + "total_days": 145, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 33, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 16, + "direct_ship_pla": 15 + } + }, + "total_from_po": 145 + }, + { + "batch": "BATCH-947566", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-15", + "earliest_gr_date": "2024-10-17", + "earliest_production_start": "2024-11-17", + "fg_receipt_date": "2025-03-07", + "qa_release_date": "2025-03-10", + "ship_date": null, + "delivery_date": "2025-04-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 40, + "total_days": 186, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 14, + "direct_ship_pla": 26 + } + }, + "total_from_po": 186 + }, + { + "batch": "BATCH-154390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-10-25", + "earliest_gr_date": "2024-10-27", + "earliest_production_start": "2024-11-27", + "fg_receipt_date": "2025-03-10", + "qa_release_date": "2025-03-16", + "ship_date": null, + "delivery_date": "2025-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 40, + "total_days": 182, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 22, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 77, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 22, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 44, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 28 + } + }, + "total_from_po": 182 + }, + { + "batch": "BATCH-557064", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-01", + "earliest_gr_date": "2024-12-03", + "earliest_production_start": "2025-01-02", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-05", + "ship_date": null, + "delivery_date": "2025-04-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 25, + "total_days": 150, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 150 + }, + { + "batch": "BATCH-307333", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-17", + "earliest_gr_date": "2024-11-19", + "earliest_production_start": "2024-12-15", + "fg_receipt_date": "2025-03-27", + "qa_release_date": "2025-04-04", + "ship_date": null, + "delivery_date": "2025-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 32, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 73, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 16 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-891817", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-02", + "earliest_gr_date": "2024-12-04", + "earliest_production_start": "2024-12-16", + "fg_receipt_date": "2025-03-30", + "qa_release_date": "2025-04-07", + "ship_date": null, + "delivery_date": "2025-05-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 14, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 76, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 25 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-852390", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-24", + "earliest_gr_date": "2024-11-26", + "earliest_production_start": "2024-12-29", + "fg_receipt_date": "2025-03-29", + "qa_release_date": "2025-04-06", + "ship_date": null, + "delivery_date": "2025-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 41, + "total_days": 174, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 27 + } + }, + "total_from_po": 174 + }, + { + "batch": "BATCH-412722", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-31", + "earliest_gr_date": "2025-01-02", + "earliest_production_start": "2025-01-21", + "fg_receipt_date": "2025-04-15", + "qa_release_date": "2025-04-20", + "ship_date": null, + "delivery_date": "2025-05-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 21, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 32, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 70, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 9, + "direct_ship_pla": 23 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-357156", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-08", + "earliest_gr_date": "2024-11-10", + "earliest_production_start": "2024-12-13", + "fg_receipt_date": "2025-04-05", + "qa_release_date": "2025-04-13", + "ship_date": null, + "delivery_date": "2025-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 45, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 110, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 72, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 83, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 60, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 14, + "direct_ship_pla": 31 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-851698", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-04", + "earliest_gr_date": "2025-01-06", + "earliest_production_start": "2025-02-06", + "fg_receipt_date": "2025-04-22", + "qa_release_date": "2025-04-30", + "ship_date": null, + "delivery_date": "2025-06-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 75, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 33, + "total_days": 149, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 52, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 71, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 54, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 7, + "direct_ship_pla": 26 + } + }, + "total_from_po": 149 + }, + { + "batch": "BATCH-440021", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-29", + "earliest_gr_date": "2024-12-31", + "earliest_production_start": "2025-01-31", + "fg_receipt_date": "2025-05-05", + "qa_release_date": "2025-05-13", + "ship_date": null, + "delivery_date": "2025-06-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 26, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 78, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 91, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 52, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 12, + "direct_ship_pla": 14 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-546123", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-12-20", + "earliest_gr_date": "2024-12-22", + "earliest_production_start": "2025-01-18", + "fg_receipt_date": "2025-05-08", + "qa_release_date": "2025-05-15", + "ship_date": null, + "delivery_date": "2025-06-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 106, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-990560", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2024-11-29", + "earliest_gr_date": "2024-12-01", + "earliest_production_start": "2025-01-08", + "fg_receipt_date": "2025-05-16", + "qa_release_date": "2025-05-24", + "ship_date": null, + "delivery_date": "2025-06-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 40, + "seg_prodstart_to_prodfinish": 128, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 25, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 109, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 125, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 49, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "direct_ship_pla": 17 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-386297", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-03", + "earliest_gr_date": "2025-01-05", + "earliest_production_start": "2025-01-29", + "fg_receipt_date": "2025-05-19", + "qa_release_date": "2025-05-26", + "ship_date": null, + "delivery_date": "2025-06-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 29, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 39, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 50, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 14, + "direct_ship_pla": 15 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-947389", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-21", + "earliest_gr_date": "2025-01-23", + "earliest_production_start": "2025-02-19", + "fg_receipt_date": "2025-05-31", + "qa_release_date": "2025-06-06", + "ship_date": null, + "delivery_date": "2025-06-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 159, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 81, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 16, + "direct_ship_pla": 7 + } + }, + "total_from_po": 159 + }, + { + "batch": "BATCH-627234", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-26", + "earliest_gr_date": "2025-01-28", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-05-29", + "qa_release_date": "2025-06-01", + "ship_date": null, + "delivery_date": "2025-07-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 34, + "total_days": 160, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 11, + "direct_ship_pla": 23 + } + }, + "total_from_po": 160 + }, + { + "batch": "BATCH-829707", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-14", + "earliest_gr_date": "2025-01-16", + "earliest_production_start": "2025-02-21", + "fg_receipt_date": "2025-06-01", + "qa_release_date": "2025-06-09", + "ship_date": null, + "delivery_date": "2025-07-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 31, + "total_days": 177, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 42, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 22 + } + }, + "total_from_po": 177 + }, + { + "batch": "BATCH-404324", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-22", + "earliest_gr_date": "2025-02-24", + "earliest_production_start": "2025-03-24", + "fg_receipt_date": "2025-06-18", + "qa_release_date": "2025-06-27", + "ship_date": null, + "delivery_date": "2025-07-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 86, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 19, + "total_days": 144, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 65, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 83, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 9, + "direct_ship_pla": 10 + } + }, + "total_from_po": 144 + }, + { + "batch": "BATCH-840018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-10", + "earliest_gr_date": "2025-02-12", + "earliest_production_start": "2025-03-15", + "fg_receipt_date": "2025-06-17", + "qa_release_date": "2025-06-21", + "ship_date": null, + "delivery_date": "2025-07-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 30, + "total_days": 161, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 64, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 77, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 12, + "direct_ship_pla": 18 + } + }, + "total_from_po": 161 + }, + { + "batch": "BATCH-243511", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-01-11", + "earliest_gr_date": "2025-01-13", + "earliest_production_start": "2025-02-13", + "fg_receipt_date": "2025-06-13", + "qa_release_date": "2025-06-22", + "ship_date": null, + "delivery_date": "2025-07-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 35, + "total_days": 197, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 100, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 116, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 53, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "direct_ship_pla": 24 + } + }, + "total_from_po": 197 + }, + { + "batch": "BATCH-394495", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-07", + "earliest_gr_date": "2025-02-09", + "earliest_production_start": "2025-03-14", + "fg_receipt_date": "2025-06-24", + "qa_release_date": "2025-07-02", + "ship_date": null, + "delivery_date": "2025-08-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 30, + "total_days": 175, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 12, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 9, + "direct_ship_pla": 21 + } + }, + "total_from_po": 175 + }, + { + "batch": "BATCH-043032", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-15", + "earliest_gr_date": "2025-02-17", + "earliest_production_start": "2025-03-11", + "fg_receipt_date": "2025-06-29", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 33, + "total_days": 173, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 8, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 8, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 63, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 82, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 30, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 41, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 23 + } + }, + "total_from_po": 173 + }, + { + "batch": "BATCH-582158", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-26", + "earliest_gr_date": "2025-02-28", + "earliest_production_start": "2025-03-23", + "fg_receipt_date": "2025-06-28", + "qa_release_date": "2025-07-05", + "ship_date": null, + "delivery_date": "2025-08-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 38, + "total_days": 167, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 15, + "direct_ship_pla": 23 + } + }, + "total_from_po": 167 + }, + { + "batch": "BATCH-302264", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-30", + "earliest_gr_date": "2025-04-01", + "earliest_production_start": "2025-04-24", + "fg_receipt_date": "2025-07-16", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-08-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 24, + "total_days": 140, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 59, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 77, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 16, + "direct_ship_pla": 8 + } + }, + "total_from_po": 140 + }, + { + "batch": "BATCH-240076", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-14", + "qa_release_date": "2025-07-21", + "ship_date": null, + "delivery_date": "2025-08-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 33, + "total_days": 151, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "direct_ship_pla": 22 + } + }, + "total_from_po": 151 + }, + { + "batch": "BATCH-804779", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-20", + "earliest_gr_date": "2025-02-22", + "earliest_production_start": "2025-03-22", + "fg_receipt_date": "2025-07-05", + "qa_release_date": "2025-07-12", + "ship_date": null, + "delivery_date": "2025-08-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 105, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 47, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 69, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 12, + "direct_ship_pla": 35 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-731192", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-15", + "earliest_gr_date": "2025-03-17", + "earliest_production_start": "2025-04-23", + "fg_receipt_date": "2025-07-22", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-09-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 39, + "seg_prodstart_to_prodfinish": 90, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 38, + "total_days": 172, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 27 + } + }, + "total_from_po": 172 + }, + { + "batch": "BATCH-482639", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-02-21", + "earliest_gr_date": "2025-02-23", + "earliest_production_start": "2025-03-30", + "fg_receipt_date": "2025-07-17", + "qa_release_date": "2025-07-24", + "ship_date": null, + "delivery_date": "2025-09-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 46, + "total_days": 199, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "direct_ship_pla": 27 + } + }, + "total_from_po": 199 + }, + { + "batch": "BATCH-062870", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-01", + "earliest_gr_date": "2025-04-03", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-01", + "qa_release_date": "2025-08-07", + "ship_date": null, + "delivery_date": "2025-09-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 38, + "total_days": 166, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 87, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 67, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 26 + } + }, + "total_from_po": 166 + }, + { + "batch": "BATCH-231165", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-05", + "earliest_gr_date": "2025-05-07", + "earliest_production_start": "2025-06-09", + "fg_receipt_date": "2025-08-16", + "qa_release_date": "2025-08-22", + "ship_date": null, + "delivery_date": "2025-09-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 68, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 28, + "total_days": 137, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 43, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "direct_ship_pla": 14 + } + }, + "total_from_po": 137 + }, + { + "batch": "BATCH-213839", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-04", + "fg_receipt_date": "2025-08-23", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-09-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 29, + "total_days": 164, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 47, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 45, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 11, + "direct_ship_pla": 18 + } + }, + "total_from_po": 164 + }, + { + "batch": "BATCH-750018", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-11", + "earliest_gr_date": "2025-05-13", + "earliest_production_start": "2025-06-05", + "fg_receipt_date": "2025-08-31", + "qa_release_date": "2025-09-06", + "ship_date": null, + "delivery_date": "2025-09-30", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 87, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 24, + "total_days": 142, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 85, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 6, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 6, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "direct_ship_pla": 17 + } + }, + "total_from_po": 142 + }, + { + "batch": "BATCH-880539", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-20", + "earliest_gr_date": "2025-04-22", + "earliest_production_start": "2025-05-26", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-10-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 85, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 41, + "total_days": 169, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 68, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 82, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 63, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 36, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 44, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 13, + "direct_ship_pla": 28 + } + }, + "total_from_po": 169 + }, + { + "batch": "BATCH-155177", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-02", + "earliest_gr_date": "2025-05-04", + "earliest_production_start": "2025-06-18", + "fg_receipt_date": "2025-09-10", + "qa_release_date": "2025-09-16", + "ship_date": null, + "delivery_date": "2025-10-11", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 47, + "seg_prodstart_to_prodfinish": 84, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 25, + "total_days": 162, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 72, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 10, + "direct_ship_pla": 15 + } + }, + "total_from_po": 162 + }, + { + "batch": "BATCH-993261", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-29", + "earliest_gr_date": "2025-05-01", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-08-30", + "qa_release_date": "2025-09-04", + "ship_date": null, + "delivery_date": "2025-10-16", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 98, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 42, + "total_days": 170, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 95, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 57, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 72, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 65, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 77, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 11, + "direct_ship_pla": 31 + } + }, + "total_from_po": 170 + }, + { + "batch": "BATCH-753433", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-27", + "earliest_gr_date": "2025-05-29", + "earliest_production_start": "2025-06-13", + "fg_receipt_date": "2025-09-23", + "qa_release_date": "2025-09-29", + "ship_date": null, + "delivery_date": "2025-10-22", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 23, + "total_days": 148, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 11, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 87, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 50, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 8, + "direct_ship_pla": 15 + } + }, + "total_from_po": 148 + }, + { + "batch": "BATCH-476897", + "route": "direct", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-21", + "earliest_gr_date": "2025-04-23", + "earliest_production_start": "2025-05-24", + "fg_receipt_date": "2025-09-14", + "qa_release_date": "2025-09-20", + "ship_date": null, + "delivery_date": "2025-10-27", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 37, + "total_days": 189, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 93, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "direct_ship_pla": 25 + } + }, + "total_from_po": 189 + }, + { + "batch": "BATCH-521582", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-03-25", + "earliest_gr_date": "2025-03-27", + "earliest_production_start": "2025-04-09", + "fg_receipt_date": "2025-07-18", + "qa_release_date": "2025-07-27", + "ship_date": null, + "delivery_date": "2025-11-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 15, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 98, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 79, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 70, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 43, + "dest_dwell_hub1": 41 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-281803", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-14", + "earliest_gr_date": "2025-04-16", + "earliest_production_start": "2025-05-07", + "fg_receipt_date": "2025-07-28", + "qa_release_date": "2025-08-01", + "ship_date": null, + "delivery_date": "2025-11-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 82, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 98, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 79, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-276962", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-05", + "earliest_gr_date": "2025-04-07", + "earliest_production_start": "2025-05-05", + "fg_receipt_date": "2025-08-17", + "qa_release_date": "2025-08-26", + "ship_date": null, + "delivery_date": "2025-11-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 79, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 101, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 16, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 69, + "production_days": 16, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-217426", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-15", + "earliest_gr_date": "2025-04-17", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-08-24", + "qa_release_date": "2025-09-03", + "ship_date": null, + "delivery_date": "2025-11-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 100, + "seg_prodfinish_to_qa": 10, + "seg_qa_to_customer": 76, + "total_days": 217, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 72, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 97, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 10, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 18, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 217 + }, + { + "batch": "BATCH-679445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-01", + "earliest_gr_date": "2025-05-03", + "earliest_production_start": "2025-06-03", + "fg_receipt_date": "2025-08-19", + "qa_release_date": "2025-08-27", + "ship_date": null, + "delivery_date": "2025-11-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 77, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 207, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 62, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 36 + } + }, + "total_from_po": 207 + }, + { + "batch": "BATCH-584703", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-19", + "earliest_gr_date": "2025-04-21", + "earliest_production_start": "2025-05-16", + "fg_receipt_date": "2025-09-06", + "qa_release_date": "2025-09-13", + "ship_date": null, + "delivery_date": "2025-11-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 27, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 77, + "total_days": 224, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 60, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 19, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 224 + }, + { + "batch": "BATCH-320907", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-03", + "earliest_gr_date": "2025-05-05", + "earliest_production_start": "2025-06-01", + "fg_receipt_date": "2025-08-12", + "qa_release_date": "2025-08-21", + "ship_date": null, + "delivery_date": "2025-12-05", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 72, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 106, + "total_days": 216, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 54, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 69, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 9, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 65, + "production_days": 9, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 216 + }, + { + "batch": "BATCH-469894", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-04-09", + "earliest_gr_date": "2025-04-11", + "earliest_production_start": "2025-05-12", + "fg_receipt_date": "2025-08-29", + "qa_release_date": "2025-09-05", + "ship_date": null, + "delivery_date": "2025-12-10", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 33, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 96, + "total_days": 245, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 89, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 105, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 71, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 45, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 56, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 245 + }, + { + "batch": "BATCH-119167", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-10", + "earliest_gr_date": "2025-05-12", + "earliest_production_start": "2025-05-30", + "fg_receipt_date": "2025-09-19", + "qa_release_date": "2025-09-26", + "ship_date": null, + "delivery_date": "2025-12-15", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 20, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 80, + "total_days": 219, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 13, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 95, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 74, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 219 + }, + { + "batch": "BATCH-850977", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-17", + "earliest_gr_date": "2025-05-19", + "earliest_production_start": "2025-06-14", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-10-01", + "ship_date": null, + "delivery_date": "2025-12-21", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 103, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 81, + "total_days": 218, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 82, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 99, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 32, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 42, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 39 + } + }, + "total_from_po": 218 + }, + { + "batch": "BATCH-315004", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-21", + "earliest_gr_date": "2025-06-23", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-10-06", + "qa_release_date": "2025-10-14", + "ship_date": null, + "delivery_date": "2025-12-26", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 36, + "seg_prodstart_to_prodfinish": 71, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 73, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 14, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 49, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 63, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 40, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 54, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 22, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-753733", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-04", + "fg_receipt_date": "2025-09-25", + "qa_release_date": "2025-09-28", + "ship_date": null, + "delivery_date": "2026-01-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 95, + "total_days": 211, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 64, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 80, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 67, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 81, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 52 + } + }, + "total_from_po": 211 + }, + { + "batch": "BATCH-006984", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-29", + "earliest_gr_date": "2025-05-31", + "earliest_production_start": "2025-06-15", + "fg_receipt_date": "2025-09-20", + "qa_release_date": "2025-09-27", + "ship_date": null, + "delivery_date": "2026-01-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 17, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 101, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 25, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 94, + "production_days": 25, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 45, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 75, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 42, + "dest_dwell_hub1": 49 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-962763", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-07-06", + "fg_receipt_date": "2025-10-26", + "qa_release_date": "2025-11-02", + "ship_date": null, + "delivery_date": "2026-01-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 32, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 71, + "total_days": 222, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 92, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 69, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 15, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 15, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 35 + } + }, + "total_from_po": 222 + }, + { + "batch": "BATCH-885445", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-04", + "earliest_gr_date": "2025-06-06", + "earliest_production_start": "2025-06-29", + "fg_receipt_date": "2025-10-03", + "qa_release_date": "2025-10-04", + "ship_date": null, + "delivery_date": "2026-01-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 25, + "seg_prodstart_to_prodfinish": 96, + "seg_prodfinish_to_qa": 1, + "seg_qa_to_customer": 105, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 10, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 10, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 1, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 63 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-622159", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-05-31", + "earliest_gr_date": "2025-06-02", + "earliest_production_start": "2025-06-26", + "fg_receipt_date": "2025-10-17", + "qa_release_date": "2025-10-23", + "ship_date": null, + "delivery_date": "2026-01-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 92, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 111, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 78, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 60, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 70, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 17, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-990714", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-03", + "earliest_gr_date": "2025-06-05", + "earliest_production_start": "2025-07-02", + "fg_receipt_date": "2025-10-14", + "qa_release_date": "2025-10-18", + "ship_date": null, + "delivery_date": "2026-01-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 104, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 102, + "total_days": 239, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 84, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 100, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 55, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 48 + } + }, + "total_from_po": 239 + }, + { + "batch": "BATCH-479016", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-14", + "earliest_gr_date": "2025-06-16", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-13", + "qa_release_date": "2025-11-19", + "ship_date": null, + "delivery_date": "2026-02-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 34, + "seg_prodstart_to_prodfinish": 118, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 76, + "total_days": 234, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 96, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 114, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 52, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 64, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 34 + } + }, + "total_from_po": 234 + }, + { + "batch": "BATCH-080863", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-26", + "earliest_gr_date": "2025-06-28", + "earliest_production_start": "2025-07-18", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-12", + "ship_date": null, + "delivery_date": "2026-02-08", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 88, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 8, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 43, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 8, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 6, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-910231", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-05", + "earliest_gr_date": "2025-07-07", + "earliest_production_start": "2025-08-11", + "fg_receipt_date": "2025-11-08", + "qa_release_date": "2025-11-16", + "ship_date": null, + "delivery_date": "2026-02-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 37, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 89, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 69, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 84, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 75, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 86, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 66, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 80, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-997425", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-07", + "earliest_gr_date": "2025-08-09", + "earliest_production_start": "2025-09-06", + "fg_receipt_date": "2025-12-04", + "qa_release_date": "2025-12-12", + "ship_date": null, + "delivery_date": "2026-02-19", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 89, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 69, + "total_days": 196, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 70, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 86, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 70, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 24, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 37, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 8, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 30 + } + }, + "total_from_po": 196 + }, + { + "batch": "BATCH-618940", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-06-19", + "earliest_gr_date": "2025-06-21", + "earliest_production_start": "2025-07-27", + "fg_receipt_date": "2025-11-29", + "qa_release_date": "2025-12-02", + "ship_date": null, + "delivery_date": "2026-02-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 125, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 84, + "total_days": 250, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 104, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 121, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 51, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 43, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 32, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 250 + }, + { + "batch": "BATCH-029240", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-07-14", + "earliest_gr_date": "2025-07-16", + "earliest_production_start": "2025-08-02", + "fg_receipt_date": "2025-11-19", + "qa_release_date": "2025-11-25", + "ship_date": null, + "delivery_date": "2026-03-02", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 109, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 231, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 104, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 77, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 88, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 15, + "transit_pla_hub1": 44, + "dest_dwell_hub1": 38 + } + }, + "total_from_po": 231 + }, + { + "batch": "BATCH-013796", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-04", + "qa_release_date": "2026-01-13", + "ship_date": null, + "delivery_date": "2026-03-07", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 38, + "seg_prodstart_to_prodfinish": 102, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 53, + "total_days": 202, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 78, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 65, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 27, + "dest_dwell_hub1": 15 + } + }, + "total_from_po": 202 + }, + { + "batch": "BATCH-563928", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-17", + "earliest_gr_date": "2025-08-19", + "earliest_production_start": "2025-09-16", + "fg_receipt_date": "2025-12-08", + "qa_release_date": "2025-12-11", + "ship_date": null, + "delivery_date": "2026-03-13", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 83, + "seg_prodfinish_to_qa": 3, + "seg_qa_to_customer": 92, + "total_days": 208, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 66, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 81, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 51, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 3, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 28, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 208 + }, + { + "batch": "BATCH-263609", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-12", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-10", + "ship_date": null, + "delivery_date": "2026-03-18", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 7, + "seg_qa_to_customer": 67, + "total_days": 215, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 26, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 83, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 26, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 20, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 74, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 57, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 7, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 15, + "dest_dwell_hub1": 42 + } + }, + "total_from_po": 215 + }, + { + "batch": "BATCH-786903", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-30", + "earliest_gr_date": "2025-09-01", + "earliest_production_start": "2025-09-23", + "fg_receipt_date": "2026-01-22", + "qa_release_date": "2026-01-28", + "ship_date": null, + "delivery_date": "2026-03-24", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 24, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 55, + "total_days": 206, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 103, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 11, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 17, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 56, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 17, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 17, + "dest_dwell_hub1": 29 + } + }, + "total_from_po": 206 + }, + { + "batch": "BATCH-676932", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-15", + "earliest_gr_date": "2025-08-17", + "earliest_production_start": "2025-09-13", + "fg_receipt_date": "2025-12-19", + "qa_release_date": "2025-12-25", + "ship_date": null, + "delivery_date": "2026-03-29", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 29, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 94, + "total_days": 226, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 73, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 16, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 35, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 51, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 59, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 9, + "transit_pla_hub1": 38, + "dest_dwell_hub1": 47 + } + }, + "total_from_po": 226 + }, + { + "batch": "BATCH-341567", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-10", + "earliest_gr_date": "2025-08-12", + "earliest_production_start": "2025-09-05", + "fg_receipt_date": "2025-12-27", + "qa_release_date": "2026-01-01", + "ship_date": null, + "delivery_date": "2026-04-04", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 26, + "seg_prodstart_to_prodfinish": 113, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 93, + "total_days": 237, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 109, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 62, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 76, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 42, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 23, + "dest_dwell_hub1": 56 + } + }, + "total_from_po": 237 + }, + { + "batch": "BATCH-162748", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-08-25", + "earliest_gr_date": "2025-08-27", + "earliest_production_start": "2025-09-24", + "fg_receipt_date": "2026-01-03", + "qa_release_date": "2026-01-09", + "ship_date": null, + "delivery_date": "2026-04-09", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 101, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 90, + "total_days": 227, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 80, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 98, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 68, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 33, + "dest_dwell_hub1": 46 + } + }, + "total_from_po": 227 + }, + { + "batch": "BATCH-322485", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-08", + "earliest_gr_date": "2025-10-10", + "earliest_production_start": "2025-10-27", + "fg_receipt_date": "2026-02-01", + "qa_release_date": "2026-02-10", + "ship_date": null, + "delivery_date": "2026-04-14", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 19, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 9, + "seg_qa_to_customer": 63, + "total_days": 188, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 76, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 50, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 64, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 10, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 38, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 10, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 9, + "post_qa_ship_pla": 11, + "transit_pla_hub1": 36, + "dest_dwell_hub1": 16 + } + }, + "total_from_po": 188 + }, + { + "batch": "BATCH-780123", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-02", + "earliest_gr_date": "2025-09-04", + "earliest_production_start": "2025-10-02", + "fg_receipt_date": "2026-01-31", + "qa_release_date": "2026-02-08", + "ship_date": null, + "delivery_date": "2026-04-20", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 30, + "seg_prodstart_to_prodfinish": 121, + "seg_prodfinish_to_qa": 8, + "seg_qa_to_customer": 71, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 101, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 118, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 55, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 71, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 3, + "prod_to_qa_pla": 8, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-219665", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-06", + "earliest_gr_date": "2025-10-08", + "earliest_production_start": "2025-10-22", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-04-25", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 16, + "seg_prodstart_to_prodfinish": 110, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 69, + "total_days": 201, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 20, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 20, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 37, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 52, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 61, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 2, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 4, + "transit_pla_hub1": 25, + "dest_dwell_hub1": 40 + } + }, + "total_from_po": 201 + }, + { + "batch": "BATCH-254225", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-08", + "earliest_gr_date": "2025-09-10", + "earliest_production_start": "2025-09-30", + "fg_receipt_date": "2026-01-28", + "qa_release_date": "2026-02-03", + "ship_date": null, + "delivery_date": "2026-05-01", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 22, + "seg_prodstart_to_prodfinish": 120, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 87, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 18, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 97, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 115, + "production_days": 18, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 54, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 66, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 61, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 73, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 5, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 29, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-311884", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-12", + "earliest_gr_date": "2025-09-14", + "earliest_production_start": "2025-10-10", + "fg_receipt_date": "2026-01-29", + "qa_release_date": "2026-02-04", + "ship_date": null, + "delivery_date": "2026-05-06", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 28, + "seg_prodstart_to_prodfinish": 111, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 91, + "total_days": 236, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 86, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 107, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 14, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 59, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 73, + "production_days": 14, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 13, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 66, + "production_days": 13, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 6, + "transit_pla_hub1": 40, + "dest_dwell_hub1": 45 + } + }, + "total_from_po": 236 + }, + { + "batch": "BATCH-534136", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-26", + "earliest_gr_date": "2025-09-28", + "earliest_production_start": "2025-11-08", + "fg_receipt_date": "2026-02-10", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-12", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 43, + "seg_prodstart_to_prodfinish": 94, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 86, + "total_days": 228, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 16, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 90, + "production_days": 16, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 12, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 49, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 61, + "production_days": 12, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 31, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 40, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 12, + "transit_pla_hub1": 30, + "dest_dwell_hub1": 44 + } + }, + "total_from_po": 228 + }, + { + "batch": "BATCH-718060", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-09-29", + "earliest_gr_date": "2025-10-01", + "earliest_production_start": "2025-11-09", + "fg_receipt_date": "2026-02-24", + "qa_release_date": "2026-02-28", + "ship_date": null, + "delivery_date": "2026-05-17", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 41, + "seg_prodstart_to_prodfinish": 107, + "seg_prodfinish_to_qa": 4, + "seg_qa_to_customer": 78, + "total_days": 230, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 15, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 88, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 103, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 19, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 48, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 67, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 12, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 41, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 53, + "production_days": 12, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 4, + "post_qa_ship_pla": 10, + "transit_pla_hub1": 14, + "dest_dwell_hub1": 54 + } + }, + "total_from_po": 230 + }, + { + "batch": "BATCH-802602", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-12", + "earliest_gr_date": "2025-10-14", + "earliest_production_start": "2025-11-04", + "fg_receipt_date": "2026-02-09", + "qa_release_date": "2026-02-15", + "ship_date": null, + "delivery_date": "2026-05-23", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 23, + "seg_prodstart_to_prodfinish": 97, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 97, + "total_days": 223, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 19, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 74, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 93, + "production_days": 19, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 13, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 46, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 59, + "production_days": 13, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 14, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 34, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 48, + "production_days": 14, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 7, + "transit_pla_hub1": 39, + "dest_dwell_hub1": 51 + } + }, + "total_from_po": 223 + }, + { + "batch": "BATCH-136204", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-05", + "earliest_gr_date": "2025-10-07", + "earliest_production_start": "2025-11-05", + "fg_receipt_date": "2026-02-25", + "qa_release_date": "2026-03-03", + "ship_date": null, + "delivery_date": "2026-05-28", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 31, + "seg_prodstart_to_prodfinish": 112, + "seg_prodfinish_to_qa": 6, + "seg_qa_to_customer": 86, + "total_days": 235, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 17, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 91, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 108, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 17, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 58, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 75, + "production_days": 17, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 11, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 47, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 58, + "production_days": 11, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 6, + "post_qa_ship_pla": 14, + "transit_pla_hub1": 53, + "dest_dwell_hub1": 19 + } + }, + "total_from_po": 235 + }, + { + "batch": "BATCH-949254", + "route": "hub-1", + "n_traced_materials": 6, + "earliest_po_date": "2025-10-14", + "earliest_gr_date": "2025-10-16", + "earliest_production_start": "2025-11-18", + "fg_receipt_date": "2026-02-19", + "qa_release_date": "2026-02-24", + "ship_date": null, + "delivery_date": "2026-06-03", + "delivery_source": "synthetic (demo)", + "seg_proc_to_prodstart": 35, + "seg_prodstart_to_prodfinish": 93, + "seg_prodfinish_to_qa": 5, + "seg_qa_to_customer": 99, + "total_days": 232, + "step_contributions": { + "upstream_chains": [ + { + "chain_id": "chain_0", + "steps": [ + { + "step_id": "prod_duration_green_blend", + "duration": 21, + "type": "production", + "material": "green_blend" + }, + { + "step_id": "intermed_dwell_green_blend", + "duration": 67, + "type": "intermediate_dwell", + "material": "green_blend" + } + ], + "total_days": 88, + "production_days": 21, + "earliest_event_date": null + }, + { + "chain_id": "chain_1", + "steps": [ + { + "step_id": "prod_duration_intermediate_beta", + "duration": 15, + "type": "production", + "material": "intermediate_beta" + }, + { + "step_id": "intermed_dwell_intermediate_beta", + "duration": 74, + "type": "intermediate_dwell", + "material": "intermediate_beta" + } + ], + "total_days": 89, + "production_days": 15, + "earliest_event_date": null + }, + { + "chain_id": "chain_2", + "steps": [ + { + "step_id": "prod_duration_intermediate_gamma", + "duration": 9, + "type": "production", + "material": "intermediate_gamma" + }, + { + "step_id": "intermed_dwell_intermediate_gamma", + "duration": 53, + "type": "intermediate_dwell", + "material": "intermediate_gamma" + } + ], + "total_days": 62, + "production_days": 9, + "earliest_event_date": null + } + ], + "post_production": { + "prod_duration_harbor_dark_roast": 4, + "prod_to_qa_pla": 5, + "post_qa_ship_pla": 13, + "transit_pla_hub1": 31, + "dest_dwell_hub1": 55 + } + }, + "total_from_po": 232 + } + ], + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.3, + "median": 30, + "p25": 25, + "p75": 34, + "n": 100 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 100.7, + "median": 102, + "p25": 90, + "p75": 112, + "n": 100 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.5, + "median": 7, + "p25": 6, + "p75": 8, + "n": 100 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 53.8, + "median": 40, + "p25": 31, + "p75": 81, + "n": 100 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 190.3, + "median": 188, + "p25": 167, + "p75": 222, + "n": 100 + } + }, + "per_route": { + "direct": { + "label": "Direct to customer", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 29.9, + "median": 30, + "p25": 26, + "p75": 35, + "n": 60 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 99.8, + "median": 101, + "p25": 90, + "p75": 110, + "n": 60 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.6, + "median": 7, + "p25": 6, + "p75": 8, + "n": 60 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 33.2, + "median": 33, + "p25": 29, + "p75": 38, + "n": 60 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 169.5, + "median": 170, + "p25": 159, + "p75": 182, + "n": 60 + } + } + }, + "hub-1": { + "label": "HUB-1", + "segments": { + "seg_proc_to_prodstart": { + "label": "Procurement \u2192 Production Start", + "mean": 28.4, + "median": 29, + "p25": 24, + "p75": 33, + "n": 40 + }, + "seg_prodstart_to_prodfinish": { + "label": "Production Start \u2192 Production Finish", + "mean": 102.1, + "median": 104, + "p25": 96, + "p75": 113, + "n": 40 + }, + "seg_prodfinish_to_qa": { + "label": "Production Finish \u2192 QA Release", + "mean": 6.2, + "median": 6, + "p25": 5, + "p75": 8, + "n": 40 + }, + "seg_qa_to_customer": { + "label": "QA Release \u2192 Customer", + "mean": 84.8, + "median": 88, + "p25": 76, + "p75": 96, + "n": 40 + }, + "total_days": { + "label": "Total (GR to Delivery)", + "mean": 221.6, + "median": 223, + "p25": 215, + "p75": 232, + "n": 40 + } + } + } + }, + "coverage": { + "traced": 100, + "total": 100 + } + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/dest_dwell_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/dest_dwell_hub1.json new file mode 100644 index 00000000000..c307305feb2 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/dest_dwell_hub1.json @@ -0,0 +1,432 @@ +{ + "id": "dest_dwell_hub1", + "label": "Destination Dwell (HUB-1)", + "type": "destination_dwell", + "durations": [ + 49.6, 76.7, 33.0, 112.1, 41.3, 11.8, 92.0, 64.9, 49.6, 37.8, 46.0, 49.6, + 54.3, 57.8, 62.5, 67.3, 56.6, 61.4, 40.1, 56.6, 35.4, 40.1, 42.5, 48.4, + 50.7, 42.5, 46.0, 49.6, 54.3, 57.8, 62.5, 53.1, 56.6, 61.4, 51.9, 56.6, 35.4 + ], + "observations": [ + { + "date": "2022-09-15", + "value": 49.6 + }, + { + "date": "2023-05-05", + "value": 76.7 + }, + { + "date": "2023-05-20", + "value": 33.0 + }, + { + "date": "2024-01-10", + "value": 112.1 + }, + { + "date": "2024-01-25", + "value": 41.3 + }, + { + "date": "2024-08-15", + "value": 11.8 + }, + { + "date": "2025-02-05", + "value": 92.0 + }, + { + "date": "2025-02-18", + "value": 64.9 + }, + { + "date": "2025-08-10", + "value": 49.6 + }, + { + "date": "2025-08-20", + "value": 37.8 + }, + { + "date": "2025-09-06", + "value": 46.0 + }, + { + "date": "2025-09-12", + "value": 49.6 + }, + { + "date": "2025-09-18", + "value": 54.3 + }, + { + "date": "2025-10-04", + "value": 57.8 + }, + { + "date": "2025-10-10", + "value": 62.5 + }, + { + "date": "2025-10-16", + "value": 67.3 + }, + { + "date": "2025-11-05", + "value": 56.6 + }, + { + "date": "2025-11-11", + "value": 61.4 + }, + { + "date": "2025-11-17", + "value": 40.1 + }, + { + "date": "2025-12-06", + "value": 56.6 + }, + { + "date": "2025-12-12", + "value": 35.4 + }, + { + "date": "2025-12-18", + "value": 40.1 + }, + { + "date": "2026-01-04", + "value": 42.5 + }, + { + "date": "2026-01-10", + "value": 48.4 + }, + { + "date": "2026-01-16", + "value": 50.7 + }, + { + "date": "2026-02-05", + "value": 42.5 + }, + { + "date": "2026-02-11", + "value": 46.0 + }, + { + "date": "2026-02-17", + "value": 49.6 + }, + { + "date": "2026-03-06", + "value": 54.3 + }, + { + "date": "2026-03-12", + "value": 57.8 + }, + { + "date": "2026-03-18", + "value": 62.5 + }, + { + "date": "2026-04-04", + "value": 53.1 + }, + { + "date": "2026-04-10", + "value": 56.6 + }, + { + "date": "2026-04-16", + "value": 61.4 + }, + { + "date": "2026-05-05", + "value": 51.9 + }, + { + "date": "2026-05-11", + "value": 56.6 + }, + { + "date": "2026-05-17", + "value": 35.4 + } + ], + "monthly": [ + { + "month": "2022-09", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "mean": 54.9, + "median": 54.9, + "p10": 37.4, + "p25": 44.0, + "p75": 65.8, + "p90": 72.3, + "n": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "mean": 76.7, + "median": 76.7, + "p10": 48.4, + "p25": 59.0, + "p75": 94.4, + "p90": 105.0, + "n": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "mean": 78.5, + "median": 78.5, + "p10": 67.6, + "p25": 71.7, + "p75": 85.3, + "p90": 89.3, + "n": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "mean": 43.7, + "median": 43.7, + "p10": 38.9, + "p25": 40.7, + "p75": 46.6, + "p90": 48.4, + "n": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "mean": 49.9, + "median": 49.6, + "p10": 46.7, + "p25": 47.8, + "p75": 51.9, + "p90": 53.3, + "n": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "mean": 62.5, + "median": 62.5, + "p10": 58.8, + "p25": 60.2, + "p75": 64.9, + "p90": 66.3, + "n": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "mean": 52.7, + "median": 56.6, + "p10": 43.4, + "p25": 48.4, + "p75": 59.0, + "p90": 60.4, + "n": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "mean": 44.0, + "median": 40.1, + "p10": 36.3, + "p25": 37.8, + "p75": 48.4, + "p90": 53.3, + "n": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "mean": 47.2, + "median": 48.4, + "p10": 43.7, + "p25": 45.4, + "p75": 49.6, + "p90": 50.3, + "n": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "mean": 46.0, + "median": 46.0, + "p10": 43.2, + "p25": 44.2, + "p75": 47.8, + "p90": 48.9, + "n": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "mean": 58.2, + "median": 57.8, + "p10": 55.0, + "p25": 56.0, + "p75": 60.2, + "p90": 61.6, + "n": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "mean": 57.0, + "median": 56.6, + "p10": 53.8, + "p25": 54.9, + "p75": 59.0, + "p90": 60.4, + "n": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "mean": 48.0, + "median": 51.9, + "p10": 38.7, + "p25": 43.7, + "p75": 54.3, + "p90": 55.7, + "n": 3, + "total_kg_days": 585600.0 + } + ], + "stats": { + "n": 37, + "mean": 53.1, + "median": 51.9, + "std": 14.0, + "min": 11.8, + "max": 112.1, + "p25": 42.5, + "p75": 57.8, + "p85": 62.5, + "p95": 76.7 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 33.63, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2022-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2023-05", + "n_events": 2, + "total_kg_days": 446400.0 + }, + { + "month": "2024-01", + "n_events": 2, + "total_kg_days": 624000.0 + }, + { + "month": "2024-08", + "n_events": 1, + "total_kg_days": 48000.0 + }, + { + "month": "2025-02", + "n_events": 2, + "total_kg_days": 638400.0 + }, + { + "month": "2025-08", + "n_events": 2, + "total_kg_days": 355200.0 + }, + { + "month": "2025-09", + "n_events": 3, + "total_kg_days": 609600.0 + }, + { + "month": "2025-10", + "n_events": 3, + "total_kg_days": 763200.0 + }, + { + "month": "2025-11", + "n_events": 3, + "total_kg_days": 643200.0 + }, + { + "month": "2025-12", + "n_events": 3, + "total_kg_days": 537600.0 + }, + { + "month": "2026-01", + "n_events": 3, + "total_kg_days": 576000.0 + }, + { + "month": "2026-02", + "n_events": 3, + "total_kg_days": 561600.0 + }, + { + "month": "2026-03", + "n_events": 3, + "total_kg_days": 710400.0 + }, + { + "month": "2026-04", + "n_events": 3, + "total_kg_days": 696000.0 + }, + { + "month": "2026-05", + "n_events": 3, + "total_kg_days": 585600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/intermed_dwell_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/intermed_dwell_green_blend.json new file mode 100644 index 00000000000..e46845bf647 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/intermed_dwell_green_blend.json @@ -0,0 +1,595 @@ +{ + "id": "intermed_dwell_green_blend", + "label": "Intermediate Dwell: Green Blend", + "type": "intermediate_dwell", + "durations": [ + 14.2, 29.5, 9.4, 41.3, 17.7, 5.9, 26.0, 21.2, 47.2, 11.8, 64.9, 2.4, 33.0, + 17.7, 9.4, 23.6, 53.1, 14.2, 3.5, 21.2, 35.4, 9.4, 26.0, 41.3, 5.9, 17.7, + 49.6, 11.8, 16.5, 18.9, 20.1, 21.2, 22.4, 16.5, 17.7, 18.9, 21.2, 13.0, + 21.2, 22.4, 23.6, 16.5, 17.7, 20.1, 22.4, 14.2, 16.5, 17.7, 20.1, 13.0, + 14.2, 15.3, 16.5, 15.3, 16.5, 18.9, 20.1, 21.2, 15.3, 16.5, 17.7, 18.9, + 21.2, 18.9, 21.2, 22.4, 23.6, 16.5, 18.9, 20.1, 22.4, 14.2, 16.5 + ], + "observations": [ + { + "date": "2022-05-05", + "value": 14.2 + }, + { + "date": "2022-05-15", + "value": 29.5 + }, + { + "date": "2022-05-22", + "value": 9.4 + }, + { + "date": "2022-11-03", + "value": 41.3 + }, + { + "date": "2022-11-10", + "value": 17.7 + }, + { + "date": "2022-11-18", + "value": 5.9 + }, + { + "date": "2022-11-25", + "value": 26.0 + }, + { + "date": "2023-05-08", + "value": 21.2 + }, + { + "date": "2023-05-15", + "value": 47.2 + }, + { + "date": "2023-05-22", + "value": 11.8 + }, + { + "date": "2023-11-06", + "value": 64.9 + }, + { + "date": "2023-11-13", + "value": 2.4 + }, + { + "date": "2023-11-20", + "value": 33.0 + }, + { + "date": "2023-11-27", + "value": 17.7 + }, + { + "date": "2023-11-30", + "value": 9.4 + }, + { + "date": "2024-05-06", + "value": 23.6 + }, + { + "date": "2024-05-13", + "value": 53.1 + }, + { + "date": "2024-05-20", + "value": 14.2 + }, + { + "date": "2024-05-27", + "value": 3.5 + }, + { + "date": "2024-11-04", + "value": 21.2 + }, + { + "date": "2024-11-11", + "value": 35.4 + }, + { + "date": "2024-11-18", + "value": 9.4 + }, + { + "date": "2025-05-05", + "value": 26.0 + }, + { + "date": "2025-05-09", + "value": 41.3 + }, + { + "date": "2025-05-13", + "value": 5.9 + }, + { + "date": "2025-05-17", + "value": 17.7 + }, + { + "date": "2025-05-21", + "value": 49.6 + }, + { + "date": "2025-05-25", + "value": 11.8 + }, + { + "date": "2025-09-05", + "value": 16.5 + }, + { + "date": "2025-09-11", + "value": 18.9 + }, + { + "date": "2025-09-17", + "value": 20.1 + }, + { + "date": "2025-09-23", + "value": 21.2 + }, + { + "date": "2025-09-29", + "value": 22.4 + }, + { + "date": "2025-10-06", + "value": 16.5 + }, + { + "date": "2025-10-12", + "value": 17.7 + }, + { + "date": "2025-10-18", + "value": 18.9 + }, + { + "date": "2025-10-24", + "value": 21.2 + }, + { + "date": "2025-10-30", + "value": 13.0 + }, + { + "date": "2025-11-04", + "value": 21.2 + }, + { + "date": "2025-11-10", + "value": 22.4 + }, + { + "date": "2025-11-16", + "value": 23.6 + }, + { + "date": "2025-11-22", + "value": 16.5 + }, + { + "date": "2025-11-28", + "value": 17.7 + }, + { + "date": "2025-12-05", + "value": 20.1 + }, + { + "date": "2025-12-11", + "value": 22.4 + }, + { + "date": "2025-12-17", + "value": 14.2 + }, + { + "date": "2025-12-23", + "value": 16.5 + }, + { + "date": "2025-12-29", + "value": 17.7 + }, + { + "date": "2026-01-06", + "value": 20.1 + }, + { + "date": "2026-01-12", + "value": 13.0 + }, + { + "date": "2026-01-18", + "value": 14.2 + }, + { + "date": "2026-01-24", + "value": 15.3 + }, + { + "date": "2026-01-30", + "value": 16.5 + }, + { + "date": "2026-02-04", + "value": 15.3 + }, + { + "date": "2026-02-10", + "value": 16.5 + }, + { + "date": "2026-02-16", + "value": 18.9 + }, + { + "date": "2026-02-22", + "value": 20.1 + }, + { + "date": "2026-02-28", + "value": 21.2 + }, + { + "date": "2026-03-05", + "value": 15.3 + }, + { + "date": "2026-03-11", + "value": 16.5 + }, + { + "date": "2026-03-17", + "value": 17.7 + }, + { + "date": "2026-03-23", + "value": 18.9 + }, + { + "date": "2026-03-29", + "value": 21.2 + }, + { + "date": "2026-04-06", + "value": 18.9 + }, + { + "date": "2026-04-12", + "value": 21.2 + }, + { + "date": "2026-04-18", + "value": 22.4 + }, + { + "date": "2026-04-24", + "value": 23.6 + }, + { + "date": "2026-04-30", + "value": 16.5 + }, + { + "date": "2026-05-04", + "value": 18.9 + }, + { + "date": "2026-05-10", + "value": 20.1 + }, + { + "date": "2026-05-16", + "value": 22.4 + }, + { + "date": "2026-05-22", + "value": 14.2 + }, + { + "date": "2026-05-28", + "value": 16.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 17.7, + "median": 14.2, + "p10": 10.4, + "p25": 11.8, + "p75": 21.8, + "p90": 26.4, + "n": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "mean": 22.8, + "median": 21.8, + "p10": 9.4, + "p25": 14.8, + "p75": 29.9, + "p90": 36.7, + "n": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "mean": 26.8, + "median": 21.2, + "p10": 13.7, + "p25": 16.5, + "p75": 34.2, + "p90": 42.0, + "n": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "mean": 25.5, + "median": 17.7, + "p10": 5.2, + "p25": 9.4, + "p75": 33.0, + "p90": 52.2, + "n": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "mean": 23.6, + "median": 18.9, + "p10": 6.7, + "p25": 11.6, + "p75": 31.0, + "p90": 44.2, + "n": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "mean": 22.1, + "median": 21.2, + "p10": 11.8, + "p25": 15.3, + "p75": 28.3, + "p90": 32.6, + "n": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "mean": 25.4, + "median": 21.8, + "p10": 8.8, + "p25": 13.3, + "p75": 37.5, + "p90": 45.4, + "n": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "mean": 19.8, + "median": 20.1, + "p10": 17.5, + "p25": 18.9, + "p75": 21.2, + "p90": 21.9, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "mean": 17.5, + "median": 17.7, + "p10": 14.4, + "p25": 16.5, + "p75": 18.9, + "p90": 20.3, + "n": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "mean": 20.3, + "median": 21.2, + "p10": 17.0, + "p25": 17.7, + "p75": 22.4, + "p90": 23.1, + "n": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "mean": 18.2, + "median": 17.7, + "p10": 15.1, + "p25": 16.5, + "p75": 20.1, + "p90": 21.5, + "n": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "mean": 15.8, + "median": 15.3, + "p10": 13.5, + "p25": 14.2, + "p75": 16.5, + "p90": 18.6, + "n": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "mean": 18.4, + "median": 18.9, + "p10": 15.8, + "p25": 16.5, + "p75": 20.1, + "p90": 20.8, + "n": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "mean": 17.9, + "median": 17.7, + "p10": 15.8, + "p25": 16.5, + "p75": 18.9, + "p90": 20.3, + "n": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "mean": 20.5, + "median": 21.2, + "p10": 17.5, + "p25": 18.9, + "p75": 22.4, + "p90": 23.1, + "n": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "mean": 18.4, + "median": 18.9, + "p10": 15.1, + "p25": 16.5, + "p75": 20.1, + "p90": 21.5, + "n": 5, + "total_kg_days": 249600.0 + } + ], + "stats": { + "n": 73, + "mean": 20.5, + "median": 18.9, + "std": 9.0, + "min": 2.4, + "max": 64.9, + "p25": 15.3, + "p75": 22.4, + "p85": 23.6, + "p95": 41.3 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 87.7, + "annotations": [], + "cost": { + "unit_price": 14.75, + "currency": "CHF", + "mean_qty": 3200.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 3, + "total_kg_days": 144000.0 + }, + { + "month": "2022-11", + "n_events": 4, + "total_kg_days": 246400.0 + }, + { + "month": "2023-05", + "n_events": 3, + "total_kg_days": 217600.0 + }, + { + "month": "2023-11", + "n_events": 5, + "total_kg_days": 345600.0 + }, + { + "month": "2024-05", + "n_events": 4, + "total_kg_days": 256000.0 + }, + { + "month": "2024-11", + "n_events": 3, + "total_kg_days": 179200.0 + }, + { + "month": "2025-05", + "n_events": 6, + "total_kg_days": 412800.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 236800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 275200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 246400.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 214400.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 249600.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 243200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 278400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 249600.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 28, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/post_qa_ship_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/post_qa_ship_pla.json new file mode 100644 index 00000000000..c77257b10be --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/post_qa_ship_pla.json @@ -0,0 +1,514 @@ +{ + "id": "post_qa_ship_pla", + "label": "Post-QA Dwell (PL-A)", + "type": "post_qa_ship", + "durations": [ + 9.4, 26.0, 49.6, 7.1, 21.2, 33.0, 14.2, 2.4, 17.7, 5.9, 23.6, 4.7, 16.5, + 17.7, 11.8, 13.0, 14.2, 16.5, 9.4, 11.8, 13.0, 13.0, 11.8, 14.2, 14.2, 15.3, + 16.5, 11.8, 13.0, 14.2, 15.3, 16.5, 15.3, 16.5, 17.7, 18.9, 13.0, 15.3, + 16.5, 17.7, 11.8, 13.0, 15.3, 16.5, 9.4, 11.8, 13.0, 18.9, 11.8, 14.2, 14.2, + 15.3, 10.6, 11.8, 13.0, 14.2, 15.3 + ], + "observations": [ + { + "date": "2023-03-10", + "value": 9.4 + }, + { + "date": "2023-03-25", + "value": 26.0 + }, + { + "date": "2023-09-20", + "value": 49.6 + }, + { + "date": "2024-03-15", + "value": 7.1 + }, + { + "date": "2024-03-28", + "value": 21.2 + }, + { + "date": "2024-09-05", + "value": 33.0 + }, + { + "date": "2024-09-15", + "value": 14.2 + }, + { + "date": "2024-09-25", + "value": 2.4 + }, + { + "date": "2025-03-10", + "value": 17.7 + }, + { + "date": "2025-03-22", + "value": 5.9 + }, + { + "date": "2025-07-08", + "value": 23.6 + }, + { + "date": "2025-07-22", + "value": 4.7 + }, + { + "date": "2025-09-05", + "value": 16.5 + }, + { + "date": "2025-09-11", + "value": 17.7 + }, + { + "date": "2025-09-17", + "value": 11.8 + }, + { + "date": "2025-09-23", + "value": 13.0 + }, + { + "date": "2025-09-29", + "value": 14.2 + }, + { + "date": "2025-10-06", + "value": 16.5 + }, + { + "date": "2025-10-12", + "value": 9.4 + }, + { + "date": "2025-10-18", + "value": 11.8 + }, + { + "date": "2025-10-24", + "value": 13.0 + }, + { + "date": "2025-10-30", + "value": 13.0 + }, + { + "date": "2025-11-04", + "value": 11.8 + }, + { + "date": "2025-11-10", + "value": 14.2 + }, + { + "date": "2025-11-16", + "value": 14.2 + }, + { + "date": "2025-11-22", + "value": 15.3 + }, + { + "date": "2025-11-28", + "value": 16.5 + }, + { + "date": "2025-12-05", + "value": 11.8 + }, + { + "date": "2025-12-11", + "value": 13.0 + }, + { + "date": "2025-12-17", + "value": 14.2 + }, + { + "date": "2025-12-23", + "value": 15.3 + }, + { + "date": "2025-12-29", + "value": 16.5 + }, + { + "date": "2026-01-06", + "value": 15.3 + }, + { + "date": "2026-01-12", + "value": 16.5 + }, + { + "date": "2026-01-18", + "value": 17.7 + }, + { + "date": "2026-01-24", + "value": 18.9 + }, + { + "date": "2026-01-30", + "value": 13.0 + }, + { + "date": "2026-02-04", + "value": 15.3 + }, + { + "date": "2026-02-10", + "value": 16.5 + }, + { + "date": "2026-02-16", + "value": 17.7 + }, + { + "date": "2026-02-22", + "value": 11.8 + }, + { + "date": "2026-02-28", + "value": 13.0 + }, + { + "date": "2026-03-05", + "value": 15.3 + }, + { + "date": "2026-03-11", + "value": 16.5 + }, + { + "date": "2026-03-17", + "value": 9.4 + }, + { + "date": "2026-03-23", + "value": 11.8 + }, + { + "date": "2026-03-29", + "value": 13.0 + }, + { + "date": "2026-04-06", + "value": 18.9 + }, + { + "date": "2026-04-12", + "value": 11.8 + }, + { + "date": "2026-04-18", + "value": 14.2 + }, + { + "date": "2026-04-24", + "value": 14.2 + }, + { + "date": "2026-04-30", + "value": 15.3 + }, + { + "date": "2026-05-04", + "value": 10.6 + }, + { + "date": "2026-05-10", + "value": 11.8 + }, + { + "date": "2026-05-16", + "value": 13.0 + }, + { + "date": "2026-05-22", + "value": 14.2 + }, + { + "date": "2026-05-28", + "value": 15.3 + } + ], + "monthly": [ + { + "month": "2023-03", + "mean": 17.7, + "median": 17.7, + "p10": 11.1, + "p25": 13.6, + "p75": 21.8, + "p90": 24.3, + "n": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "mean": 14.2, + "median": 14.2, + "p10": 8.5, + "p25": 10.6, + "p75": 17.7, + "p90": 19.8, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "mean": 16.5, + "median": 14.2, + "p10": 4.7, + "p25": 8.3, + "p75": 23.6, + "p90": 29.3, + "n": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "mean": 11.8, + "median": 11.8, + "p10": 7.1, + "p25": 8.8, + "p75": 14.8, + "p90": 16.5, + "n": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "mean": 14.2, + "median": 14.2, + "p10": 6.6, + "p25": 9.4, + "p75": 18.9, + "p90": 21.7, + "n": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "mean": 14.6, + "median": 14.2, + "p10": 12.3, + "p25": 13.0, + "p75": 16.5, + "p90": 17.2, + "n": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "mean": 12.7, + "median": 13.0, + "p10": 10.4, + "p25": 11.8, + "p75": 13.0, + "p90": 15.1, + "n": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "mean": 14.4, + "median": 14.2, + "p10": 12.7, + "p25": 14.2, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "mean": 14.2, + "median": 14.2, + "p10": 12.3, + "p25": 13.0, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "mean": 16.3, + "median": 16.5, + "p10": 13.9, + "p25": 15.3, + "p75": 17.7, + "p90": 18.4, + "n": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "mean": 14.9, + "median": 15.3, + "p10": 12.3, + "p25": 13.0, + "p75": 16.5, + "p90": 17.2, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "mean": 13.2, + "median": 13.0, + "p10": 10.4, + "p25": 11.8, + "p75": 15.3, + "p90": 16.0, + "n": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "mean": 14.9, + "median": 14.2, + "p10": 12.7, + "p25": 14.2, + "p75": 15.3, + "p90": 17.5, + "n": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "mean": 13.0, + "median": 13.0, + "p10": 11.1, + "p25": 11.8, + "p75": 14.2, + "p90": 14.9, + "n": 5, + "total_kg_days": 264000.0 + } + ], + "stats": { + "n": 57, + "mean": 15.0, + "median": 14.2, + "std": 5.6, + "min": 2.4, + "max": 49.6, + "p25": 11.8, + "p75": 16.5, + "p85": 17.7, + "p95": 23.6 + }, + "plifz": null, + "plifz_note": null, + "pct_exceeding_plifz": null, + "annotations": [], + "cost": { + "unit_price": 33.63, + "currency": "CHF", + "mean_qty": 4800.0, + "monthly": [ + { + "month": "2023-03", + "n_events": 2, + "total_kg_days": 144000.0 + }, + { + "month": "2023-09", + "n_events": 1, + "total_kg_days": 201600.0 + }, + { + "month": "2024-03", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2024-09", + "n_events": 3, + "total_kg_days": 201600.0 + }, + { + "month": "2025-03", + "n_events": 2, + "total_kg_days": 96000.0 + }, + { + "month": "2025-07", + "n_events": 2, + "total_kg_days": 115200.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 297600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 259200.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 292800.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 288000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 331200.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 268800.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 302400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 264000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 12, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_highland_arabica.json new file mode 100644 index 00000000000..740a22bac55 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_highland_arabica.json @@ -0,0 +1,3304 @@ +{ + "id": "procurement_highland_arabica", + "label": "Procurement: Highland Arabica", + "type": "procurement", + "durations": [ + 64.9, 49.6, 9.4, 74.3, 44.8, 26.0, 83.8, 35.4, 53.1, 21.2, 123.9, 41.3, + 14.2, 56.6, 46.0, 48.4, 51.9, 56.6, 60.2, 43.7, 47.2, 51.9, 55.5, 36.6, + 42.5, 47.2, 50.7, 31.9, 36.6, 54.3, 57.8, 38.9, 43.7, 46.0, 53.1, 34.2, + 38.9, 41.3, 44.8, 41.3, 46.0, 48.4, 51.9, 56.6, 41.3, 43.7, 47.2, 51.9, + 55.5, 38.9, 42.5, 47.2, 50.7, 31.9, 49.6, 54.3, 57.8, 38.9, 43.7 + ], + "observations": [ + { + "date": "2022-03-15", + "value": 64.9 + }, + { + "date": "2022-06-10", + "value": 49.6 + }, + { + "date": "2022-09-22", + "value": 9.4 + }, + { + "date": "2022-12-05", + "value": 74.3 + }, + { + "date": "2023-02-14", + "value": 44.8 + }, + { + "date": "2023-05-30", + "value": 26.0 + }, + { + "date": "2023-08-17", + "value": 83.8 + }, + { + "date": "2023-11-02", + "value": 35.4 + }, + { + "date": "2024-01-25", + "value": 53.1 + }, + { + "date": "2024-04-11", + "value": 21.2 + }, + { + "date": "2024-07-09", + "value": 123.9 + }, + { + "date": "2024-10-03", + "value": 41.3 + }, + { + "date": "2025-01-20", + "value": 14.2 + }, + { + "date": "2025-04-08", + "value": 56.6 + }, + { + "date": "2025-09-05", + "value": 46.0 + }, + { + "date": "2025-09-11", + "value": 48.4 + }, + { + "date": "2025-09-17", + "value": 51.9 + }, + { + "date": "2025-09-23", + "value": 56.6 + }, + { + "date": "2025-09-29", + "value": 60.2 + }, + { + "date": "2025-10-06", + "value": 43.7 + }, + { + "date": "2025-10-12", + "value": 47.2 + }, + { + "date": "2025-10-18", + "value": 51.9 + }, + { + "date": "2025-10-24", + "value": 55.5 + }, + { + "date": "2025-10-30", + "value": 36.6 + }, + { + "date": "2025-11-04", + "value": 42.5 + }, + { + "date": "2025-11-10", + "value": 47.2 + }, + { + "date": "2025-11-16", + "value": 50.7 + }, + { + "date": "2025-11-22", + "value": 31.9 + }, + { + "date": "2025-11-28", + "value": 36.6 + }, + { + "date": "2025-12-05", + "value": 54.3 + }, + { + "date": "2025-12-11", + "value": 57.8 + }, + { + "date": "2025-12-17", + "value": 38.9 + }, + { + "date": "2025-12-23", + "value": 43.7 + }, + { + "date": "2025-12-29", + "value": 46.0 + }, + { + "date": "2026-01-06", + "value": 53.1 + }, + { + "date": "2026-01-12", + "value": 34.2 + }, + { + "date": "2026-01-18", + "value": 38.9 + }, + { + "date": "2026-01-24", + "value": 41.3 + }, + { + "date": "2026-01-30", + "value": 44.8 + }, + { + "date": "2026-02-04", + "value": 41.3 + }, + { + "date": "2026-02-10", + "value": 46.0 + }, + { + "date": "2026-02-16", + "value": 48.4 + }, + { + "date": "2026-02-22", + "value": 51.9 + }, + { + "date": "2026-02-28", + "value": 56.6 + }, + { + "date": "2026-03-05", + "value": 41.3 + }, + { + "date": "2026-03-11", + "value": 43.7 + }, + { + "date": "2026-03-17", + "value": 47.2 + }, + { + "date": "2026-03-23", + "value": 51.9 + }, + { + "date": "2026-03-29", + "value": 55.5 + }, + { + "date": "2026-04-06", + "value": 38.9 + }, + { + "date": "2026-04-12", + "value": 42.5 + }, + { + "date": "2026-04-18", + "value": 47.2 + }, + { + "date": "2026-04-24", + "value": 50.7 + }, + { + "date": "2026-04-30", + "value": 31.9 + }, + { + "date": "2026-05-04", + "value": 49.6 + }, + { + "date": "2026-05-10", + "value": 54.3 + }, + { + "date": "2026-05-16", + "value": 57.8 + }, + { + "date": "2026-05-22", + "value": 38.9 + }, + { + "date": "2026-05-28", + "value": 43.7 + } + ], + "monthly": [ + { + "month": "2022-03", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2022-06", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1 + }, + { + "month": "2022-09", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2022-12", + "mean": 74.3, + "median": 74.3, + "p10": 74.3, + "p25": 74.3, + "p75": 74.3, + "p90": 74.3, + "n": 1 + }, + { + "month": "2023-02", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2023-08", + "mean": 83.8, + "median": 83.8, + "p10": 83.8, + "p25": 83.8, + "p75": 83.8, + "p90": 83.8, + "n": 1 + }, + { + "month": "2023-11", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2024-01", + "mean": 53.1, + "median": 53.1, + "p10": 53.1, + "p25": 53.1, + "p75": 53.1, + "p90": 53.1, + "n": 1 + }, + { + "month": "2024-04", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2024-07", + "mean": 123.9, + "median": 123.9, + "p10": 123.9, + "p25": 123.9, + "p75": 123.9, + "p90": 123.9, + "n": 1 + }, + { + "month": "2024-10", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2025-01", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2025-04", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2025-09", + "mean": 52.6, + "median": 51.9, + "p10": 47.0, + "p25": 48.4, + "p75": 56.6, + "p90": 58.8, + "n": 5 + }, + { + "month": "2025-10", + "mean": 47.0, + "median": 47.2, + "p10": 39.4, + "p25": 43.7, + "p75": 51.9, + "p90": 54.0, + "n": 5 + }, + { + "month": "2025-11", + "mean": 41.8, + "median": 42.5, + "p10": 33.7, + "p25": 36.6, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2025-12", + "mean": 48.1, + "median": 46.0, + "p10": 40.8, + "p25": 43.7, + "p75": 54.3, + "p90": 56.4, + "n": 5 + }, + { + "month": "2026-01", + "mean": 42.5, + "median": 41.3, + "p10": 36.1, + "p25": 38.9, + "p75": 44.8, + "p90": 49.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 48.9, + "median": 48.4, + "p10": 43.2, + "p25": 46.0, + "p75": 51.9, + "p90": 54.8, + "n": 5 + }, + { + "month": "2026-03", + "mean": 47.9, + "median": 47.2, + "p10": 42.2, + "p25": 43.7, + "p75": 51.9, + "p90": 54.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 42.2, + "median": 42.5, + "p10": 34.7, + "p25": 38.9, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 48.9, + "median": 49.6, + "p10": 40.8, + "p25": 43.7, + "p75": 54.3, + "p90": 56.4, + "n": 5 + } + ], + "stats": { + "n": 59, + "mean": 47.4, + "median": 47.2, + "std": 13.3, + "min": 9.4, + "max": 123.9, + "p25": 41.3, + "p75": 53.1, + "p85": 56.6, + "p95": 64.9 + }, + "plifz": 10, + "plifz_note": null, + "pct_exceeding_plifz": 98.3, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_highland_arabica", + "po_number": "4500000003", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000003", + "first_gr_date": "2025-06-03", + "days_vs_promised": -2, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000000", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000000", + "first_gr_date": "2025-06-06", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000005", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000005", + "first_gr_date": "2025-06-13", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000001", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000001", + "first_gr_date": "2025-06-15", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000002", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000002", + "first_gr_date": "2025-06-20", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000004", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000004", + "first_gr_date": "2025-06-21", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000006", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000006", + "first_gr_date": "2025-07-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000007", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000007", + "first_gr_date": "2025-07-10", + "days_vs_promised": 4, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000009", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000009", + "first_gr_date": "2025-07-21", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000010", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000010", + "first_gr_date": "2025-07-26", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000008", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000008", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000012", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000012", + "first_gr_date": "2025-08-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000013", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000013", + "first_gr_date": "2025-08-20", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000014", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000014", + "first_gr_date": "2025-08-23", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000011", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000011", + "first_gr_date": "2025-08-25", + "days_vs_promised": 6, + "lead_time_days": 49 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000015", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000015", + "first_gr_date": "2025-08-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000016", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000016", + "first_gr_date": "2025-09-25", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000019", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000019", + "first_gr_date": "2025-09-27", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000020", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000020", + "first_gr_date": "2025-10-03", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000017", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000017", + "first_gr_date": "2025-10-05", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000018", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000018", + "first_gr_date": "2025-10-10", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000022", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000022", + "first_gr_date": "2025-10-16", + "days_vs_promised": -1, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000021", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000021", + "first_gr_date": "2025-10-19", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000023", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000023", + "first_gr_date": "2025-10-31", + "days_vs_promised": 2, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000024", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000024", + "first_gr_date": "2025-11-01", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000025", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000025", + "first_gr_date": "2025-11-17", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000027", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000027", + "first_gr_date": "2025-11-29", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000028", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000028", + "first_gr_date": "2025-12-03", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000026", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000026", + "first_gr_date": "2025-12-04", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000029", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000029", + "first_gr_date": "2025-12-19", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000030", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000030", + "first_gr_date": "2025-12-24", + "days_vs_promised": 1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000034", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000034", + "first_gr_date": "2026-01-11", + "days_vs_promised": -2, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000031", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000031", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000033", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000033", + "first_gr_date": "2026-01-13", + "days_vs_promised": -2, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000035", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000035", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000032", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000032", + "first_gr_date": "2026-01-17", + "days_vs_promised": 0, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000036", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000036", + "first_gr_date": "2026-01-31", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000037", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000037", + "first_gr_date": "2026-02-08", + "days_vs_promised": -2, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000038", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000038", + "first_gr_date": "2026-02-11", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000040", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000040", + "first_gr_date": "2026-02-25", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000039", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000039", + "first_gr_date": "2026-03-01", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000041", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000041", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000042", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000042", + "first_gr_date": "2026-03-18", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000043", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000043", + "first_gr_date": "2026-03-22", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000044", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000044", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000045", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000045", + "first_gr_date": "2026-03-27", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000057", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000057", + "first_gr_date": "2026-04-01", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000068", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000068", + "first_gr_date": "2026-04-07", + "days_vs_promised": 4, + "lead_time_days": 42 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000069", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000069", + "first_gr_date": "2026-04-09", + "days_vs_promised": 3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000056", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000056", + "first_gr_date": "2026-04-10", + "days_vs_promised": 1, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000058", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000058", + "first_gr_date": "2026-04-12", + "days_vs_promised": 5, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000071", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000071", + "first_gr_date": "2026-04-13", + "days_vs_promised": -3, + "lead_time_days": 27 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000060", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000060", + "first_gr_date": "2026-04-14", + "days_vs_promised": 1, + "lead_time_days": 21 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000048", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000048", + "first_gr_date": "2026-04-22", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000050", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000050", + "first_gr_date": "2026-04-27", + "days_vs_promised": -3, + "lead_time_days": 20 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000046", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000046", + "first_gr_date": "2026-04-29", + "days_vs_promised": 3, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000047", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000047", + "first_gr_date": "2026-05-01", + "days_vs_promised": -2, + "lead_time_days": 44 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000059", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000059", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000049", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000049", + "first_gr_date": "2026-05-06", + "days_vs_promised": -3, + "lead_time_days": 36 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000074", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000074", + "first_gr_date": "2026-05-06", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000063", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000063", + "first_gr_date": "2026-05-07", + "days_vs_promised": 0, + "lead_time_days": 24 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000051", + "po_item": "00020", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000051", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 26 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000070", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000070", + "first_gr_date": "2026-05-12", + "days_vs_promised": 20, + "lead_time_days": 64 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000075", + "po_item": "00030", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000075", + "first_gr_date": "2026-05-15", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000061", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000061", + "first_gr_date": "2026-05-18", + "days_vs_promised": -3, + "lead_time_days": 47 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000065", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000065", + "first_gr_date": "2026-05-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000072", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000072", + "first_gr_date": "2026-05-21", + "days_vs_promised": 18, + "lead_time_days": 58 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000062", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000062", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000053", + "po_item": "00040", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000053", + "first_gr_date": "2026-05-29", + "days_vs_promised": 0, + "lead_time_days": 31 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000077", + "po_item": "00050", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000077", + "first_gr_date": "2026-06-02", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000078", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000078", + "first_gr_date": "2026-06-03", + "days_vs_promised": -3, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000076", + "po_item": "00040", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000076", + "first_gr_date": "2026-06-04", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000064", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000064", + "first_gr_date": "2026-06-05", + "days_vs_promised": -1, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000052", + "po_item": "00030", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000052", + "first_gr_date": "2026-06-06", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000073", + "po_item": "00010", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000073", + "first_gr_date": "2026-06-07", + "days_vs_promised": 30, + "lead_time_days": 68 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000079", + "po_item": "00020", + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000079", + "first_gr_date": "2026-06-09", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000054", + "po_item": "00050", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000054", + "first_gr_date": "2026-06-13", + "days_vs_promised": 0, + "lead_time_days": 37 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000055", + "po_item": "00010", + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000055", + "first_gr_date": "2026-06-13", + "days_vs_promised": -2, + "lead_time_days": 33 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000066", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000066", + "first_gr_date": "2026-06-16", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_highland_arabica", + "po_number": "4500000067", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000067", + "first_gr_date": "2026-06-22", + "days_vs_promised": 18, + "lead_time_days": 39 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 14, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0002", + "name": "Cascadia Coffee Traders" + }, + "vendors": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "n_lines": 56, + "n_late": 5, + "on_time_pct": 91.1, + "in_full_pct": 100.0, + "otif_pct": 91.1, + "mean_days_late_all": 0.29, + "mean_days_late_when_late": 3.2, + "median_days_late_when_late": 3, + "max_days_late": 6, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 8.9, + "ge_3d_pct": 5.4, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 12, + "n_late": 4, + "on_time_pct": 66.7, + "in_full_pct": 100.0, + "otif_pct": 66.7, + "mean_days_late_all": 2.08, + "mean_days_late_when_late": 6.2, + "median_days_late_when_late": 3.0, + "max_days_late": 18, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 33.3, + "ge_3d_pct": 16.7, + "ge_7d_pct": 8.3, + "ge_14d_pct": 8.3 + } + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "n_lines": 12, + "n_late": 5, + "on_time_pct": 58.3, + "in_full_pct": 100.0, + "otif_pct": 58.3, + "mean_days_late_all": 6.25, + "mean_days_late_when_late": 15, + "median_days_late_when_late": 18, + "max_days_late": 30, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 41.7, + "ge_3d_pct": 41.7, + "ge_7d_pct": 25.0, + "ge_14d_pct": 25.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0 + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 80, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000000", + "po_item": "00010", + "po_date": "2025-04-23", + "promised_date": "2025-06-08", + "first_gr_date": "2025-06-06", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000001", + "po_item": "00020", + "po_date": "2025-05-01", + "promised_date": "2025-06-17", + "first_gr_date": "2025-06-15", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000002", + "po_item": "00030", + "po_date": "2025-05-06", + "promised_date": "2025-06-20", + "first_gr_date": "2025-06-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000003", + "po_item": "00040", + "po_date": "2025-05-14", + "promised_date": "2025-06-05", + "first_gr_date": "2025-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000004", + "po_item": "00050", + "po_date": "2025-05-22", + "promised_date": "2025-06-24", + "first_gr_date": "2025-06-21", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000005", + "po_item": "00010", + "po_date": "2025-05-27", + "promised_date": "2025-06-16", + "first_gr_date": "2025-06-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000006", + "po_item": "00020", + "po_date": "2025-06-02", + "promised_date": "2025-07-10", + "first_gr_date": "2025-07-09", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000007", + "po_item": "00030", + "po_date": "2025-06-11", + "promised_date": "2025-07-06", + "first_gr_date": "2025-07-10", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000008", + "po_item": "00040", + "po_date": "2025-06-19", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000009", + "po_item": "00050", + "po_date": "2025-06-25", + "promised_date": "2025-07-23", + "first_gr_date": "2025-07-21", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000010", + "po_item": "00010", + "po_date": "2025-06-30", + "promised_date": "2025-07-26", + "first_gr_date": "2025-07-26", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000011", + "po_item": "00020", + "po_date": "2025-07-07", + "promised_date": "2025-08-19", + "first_gr_date": "2025-08-25", + "days_late": 6, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000012", + "po_item": "00030", + "po_date": "2025-07-15", + "promised_date": "2025-08-07", + "first_gr_date": "2025-08-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000013", + "po_item": "00040", + "po_date": "2025-07-23", + "promised_date": "2025-08-20", + "first_gr_date": "2025-08-20", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000014", + "po_item": "00050", + "po_date": "2025-07-28", + "promised_date": "2025-08-23", + "first_gr_date": "2025-08-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000015", + "po_item": "00010", + "po_date": "2025-08-04", + "promised_date": "2025-08-27", + "first_gr_date": "2025-08-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000016", + "po_item": "00020", + "po_date": "2025-08-13", + "promised_date": "2025-09-25", + "first_gr_date": "2025-09-25", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000017", + "po_item": "00030", + "po_date": "2025-08-21", + "promised_date": "2025-10-05", + "first_gr_date": "2025-10-05", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000018", + "po_item": "00040", + "po_date": "2025-08-26", + "promised_date": "2025-10-12", + "first_gr_date": "2025-10-10", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000019", + "po_item": "00050", + "po_date": "2025-09-04", + "promised_date": "2025-09-28", + "first_gr_date": "2025-09-27", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000020", + "po_item": "00010", + "po_date": "2025-09-09", + "promised_date": "2025-10-03", + "first_gr_date": "2025-10-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000021", + "po_item": "00020", + "po_date": "2025-09-17", + "promised_date": "2025-10-22", + "first_gr_date": "2025-10-19", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000022", + "po_item": "00030", + "po_date": "2025-09-23", + "promised_date": "2025-10-17", + "first_gr_date": "2025-10-16", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000023", + "po_item": "00040", + "po_date": "2025-10-01", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-31", + "days_late": 2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000024", + "po_item": "00050", + "po_date": "2025-10-08", + "promised_date": "2025-11-01", + "first_gr_date": "2025-11-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000025", + "po_item": "00010", + "po_date": "2025-10-14", + "promised_date": "2025-11-19", + "first_gr_date": "2025-11-17", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000026", + "po_item": "00020", + "po_date": "2025-10-21", + "promised_date": "2025-12-04", + "first_gr_date": "2025-12-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000027", + "po_item": "00030", + "po_date": "2025-10-29", + "promised_date": "2025-12-01", + "first_gr_date": "2025-11-29", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000028", + "po_item": "00040", + "po_date": "2025-11-04", + "promised_date": "2025-12-03", + "first_gr_date": "2025-12-03", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000029", + "po_item": "00050", + "po_date": "2025-11-10", + "promised_date": "2025-12-19", + "first_gr_date": "2025-12-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000030", + "po_item": "00010", + "po_date": "2025-11-20", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-24", + "days_late": 1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000031", + "po_item": "00020", + "po_date": "2025-11-27", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000032", + "po_item": "00030", + "po_date": "2025-12-04", + "promised_date": "2026-01-17", + "first_gr_date": "2026-01-17", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000033", + "po_item": "00040", + "po_date": "2025-12-10", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000034", + "po_item": "00050", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000035", + "po_item": "00010", + "po_date": "2025-12-24", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000036", + "po_item": "00020", + "po_date": "2025-12-31", + "promised_date": "2026-02-01", + "first_gr_date": "2026-01-31", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000037", + "po_item": "00030", + "po_date": "2026-01-08", + "promised_date": "2026-02-10", + "first_gr_date": "2026-02-08", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000038", + "po_item": "00040", + "po_date": "2026-01-13", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-11", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000039", + "po_item": "00050", + "po_date": "2026-01-20", + "promised_date": "2026-03-01", + "first_gr_date": "2026-03-01", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000040", + "po_item": "00010", + "po_date": "2026-01-29", + "promised_date": "2026-02-25", + "first_gr_date": "2026-02-25", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000041", + "po_item": "00020", + "po_date": "2026-02-03", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000042", + "po_item": "00030", + "po_date": "2026-02-11", + "promised_date": "2026-03-18", + "first_gr_date": "2026-03-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000043", + "po_item": "00040", + "po_date": "2026-02-16", + "promised_date": "2026-03-23", + "first_gr_date": "2026-03-22", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000044", + "po_item": "00050", + "po_date": "2026-02-26", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000045", + "po_item": "00010", + "po_date": "2026-03-04", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000046", + "po_item": "00020", + "po_date": "2026-03-10", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-29", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000047", + "po_item": "00030", + "po_date": "2026-03-18", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-01", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000048", + "po_item": "00040", + "po_date": "2026-03-25", + "promised_date": "2026-04-22", + "first_gr_date": "2026-04-22", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000049", + "po_item": "00050", + "po_date": "2026-03-31", + "promised_date": "2026-05-09", + "first_gr_date": "2026-05-06", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000050", + "po_item": "00010", + "po_date": "2026-04-07", + "promised_date": "2026-04-30", + "first_gr_date": "2026-04-27", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000051", + "po_item": "00020", + "po_date": "2026-04-15", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000052", + "po_item": "00030", + "po_date": "2026-04-22", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000053", + "po_item": "00040", + "po_date": "2026-04-28", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-29", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000054", + "po_item": "00050", + "po_date": "2026-05-07", + "promised_date": "2026-06-13", + "first_gr_date": "2026-06-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0002", + "vendor_name": "Cascadia Coffee Traders", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000055", + "po_item": "00010", + "po_date": "2026-05-11", + "promised_date": "2026-06-15", + "first_gr_date": "2026-06-13", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000056", + "po_item": "00010", + "po_date": "2026-02-25", + "promised_date": "2026-04-09", + "first_gr_date": "2026-04-10", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000057", + "po_item": "00020", + "po_date": "2026-03-02", + "promised_date": "2026-04-01", + "first_gr_date": "2026-04-01", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000058", + "po_item": "00030", + "po_date": "2026-03-11", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-12", + "days_late": 5, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000059", + "po_item": "00040", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000060", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-14", + "days_late": 1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000061", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-18", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000062", + "po_item": "00020", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000063", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-07", + "first_gr_date": "2026-05-07", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000064", + "po_item": "00040", + "po_date": "2026-04-21", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-05", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000065", + "po_item": "00050", + "po_date": "2026-04-27", + "promised_date": "2026-05-19", + "first_gr_date": "2026-05-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000066", + "po_item": "00010", + "po_date": "2026-05-04", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000067", + "po_item": "00020", + "po_date": "2026-05-14", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-22", + "days_late": 18, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000068", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-07", + "days_late": 4, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000069", + "po_item": "00020", + "po_date": "2026-03-04", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-09", + "days_late": 3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000070", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-22", + "first_gr_date": "2026-05-12", + "days_late": 20, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000071", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000072", + "po_item": "00050", + "po_date": "2026-03-24", + "promised_date": "2026-05-03", + "first_gr_date": "2026-05-21", + "days_late": 18, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000073", + "po_item": "00010", + "po_date": "2026-03-31", + "promised_date": "2026-05-08", + "first_gr_date": "2026-06-07", + "days_late": 30, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000074", + "po_item": "00020", + "po_date": "2026-04-08", + "promised_date": "2026-05-06", + "first_gr_date": "2026-05-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000075", + "po_item": "00030", + "po_date": "2026-04-13", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-15", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000076", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-04", + "first_gr_date": "2026-06-04", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000077", + "po_item": "00050", + "po_date": "2026-04-29", + "promised_date": "2026-06-02", + "first_gr_date": "2026-06-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000078", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-06", + "first_gr_date": "2026-06-03", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0006", + "vendor_name": "Latezone Trading Co.", + "matnr": "demo_highland_arabica", + "material_name": "Highland Arabica", + "po_number": "4500000079", + "po_item": "00020", + "po_date": "2026-05-12", + "promised_date": "2026-06-09", + "first_gr_date": "2026-06-09", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_lowland_robusta.json new file mode 100644 index 00000000000..5dc3478c076 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_lowland_robusta.json @@ -0,0 +1,2575 @@ +{ + "id": "procurement_lowland_robusta", + "label": "Procurement: Lowland Robusta", + "type": "procurement", + "durations": [ + 37.8, 56.6, 5.9, 79.1, 29.5, 48.4, 17.7, 96.8, 44.8, 23.6, 61.4, 11.8, 51.9, + 33.0, 41.3, 21.2, 64.9, 30.7, 30.7, 34.2, 36.6, 40.1, 43.7, 30.7, 33.0, + 36.6, 38.9, 42.5, 38.9, 42.5, 44.8, 49.6, 33.0, 37.8, 41.3, 44.8, 28.3, + 33.0, 47.2, 50.7, 34.2, 38.9, 41.3, 47.2, 30.7, 34.2, 36.6, 40.1, 26.0, + 30.7, 33.0, 36.6, 38.9, 36.6, 38.9, 42.5, 44.8, 49.6, 35.4, 37.8, 41.3, + 44.8, 28.3 + ], + "observations": [ + { + "date": "2022-02-08", + "value": 37.8 + }, + { + "date": "2022-04-19", + "value": 56.6 + }, + { + "date": "2022-07-11", + "value": 5.9 + }, + { + "date": "2022-09-28", + "value": 79.1 + }, + { + "date": "2022-12-15", + "value": 29.5 + }, + { + "date": "2023-03-07", + "value": 48.4 + }, + { + "date": "2023-05-22", + "value": 17.7 + }, + { + "date": "2023-08-09", + "value": 96.8 + }, + { + "date": "2023-10-30", + "value": 44.8 + }, + { + "date": "2024-01-16", + "value": 23.6 + }, + { + "date": "2024-03-25", + "value": 61.4 + }, + { + "date": "2024-06-12", + "value": 11.8 + }, + { + "date": "2024-08-28", + "value": 51.9 + }, + { + "date": "2024-11-14", + "value": 33.0 + }, + { + "date": "2025-01-06", + "value": 41.3 + }, + { + "date": "2025-03-18", + "value": 21.2 + }, + { + "date": "2025-05-29", + "value": 64.9 + }, + { + "date": "2025-08-12", + "value": 30.7 + }, + { + "date": "2025-09-04", + "value": 30.7 + }, + { + "date": "2025-09-10", + "value": 34.2 + }, + { + "date": "2025-09-16", + "value": 36.6 + }, + { + "date": "2025-09-22", + "value": 40.1 + }, + { + "date": "2025-09-28", + "value": 43.7 + }, + { + "date": "2025-10-05", + "value": 30.7 + }, + { + "date": "2025-10-11", + "value": 33.0 + }, + { + "date": "2025-10-17", + "value": 36.6 + }, + { + "date": "2025-10-23", + "value": 38.9 + }, + { + "date": "2025-10-29", + "value": 42.5 + }, + { + "date": "2025-11-06", + "value": 38.9 + }, + { + "date": "2025-11-12", + "value": 42.5 + }, + { + "date": "2025-11-18", + "value": 44.8 + }, + { + "date": "2025-11-24", + "value": 49.6 + }, + { + "date": "2025-11-30", + "value": 33.0 + }, + { + "date": "2025-12-04", + "value": 37.8 + }, + { + "date": "2025-12-10", + "value": 41.3 + }, + { + "date": "2025-12-16", + "value": 44.8 + }, + { + "date": "2025-12-22", + "value": 28.3 + }, + { + "date": "2025-12-28", + "value": 33.0 + }, + { + "date": "2026-01-05", + "value": 47.2 + }, + { + "date": "2026-01-11", + "value": 50.7 + }, + { + "date": "2026-01-17", + "value": 34.2 + }, + { + "date": "2026-01-23", + "value": 38.9 + }, + { + "date": "2026-01-29", + "value": 41.3 + }, + { + "date": "2026-02-06", + "value": 47.2 + }, + { + "date": "2026-02-12", + "value": 30.7 + }, + { + "date": "2026-02-18", + "value": 34.2 + }, + { + "date": "2026-02-24", + "value": 36.6 + }, + { + "date": "2026-02-30", + "value": 40.1 + }, + { + "date": "2026-03-04", + "value": 26.0 + }, + { + "date": "2026-03-10", + "value": 30.7 + }, + { + "date": "2026-03-16", + "value": 33.0 + }, + { + "date": "2026-03-22", + "value": 36.6 + }, + { + "date": "2026-03-28", + "value": 38.9 + }, + { + "date": "2026-04-05", + "value": 36.6 + }, + { + "date": "2026-04-11", + "value": 38.9 + }, + { + "date": "2026-04-17", + "value": 42.5 + }, + { + "date": "2026-04-23", + "value": 44.8 + }, + { + "date": "2026-04-29", + "value": 49.6 + }, + { + "date": "2026-05-06", + "value": 35.4 + }, + { + "date": "2026-05-12", + "value": 37.8 + }, + { + "date": "2026-05-18", + "value": 41.3 + }, + { + "date": "2026-05-24", + "value": 44.8 + }, + { + "date": "2026-05-30", + "value": 28.3 + } + ], + "monthly": [ + { + "month": "2022-02", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2022-04", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-09", + "mean": 79.1, + "median": 79.1, + "p10": 79.1, + "p25": 79.1, + "p75": 79.1, + "p90": 79.1, + "n": 1 + }, + { + "month": "2022-12", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 48.4, + "median": 48.4, + "p10": 48.4, + "p25": 48.4, + "p75": 48.4, + "p90": 48.4, + "n": 1 + }, + { + "month": "2023-05", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2023-08", + "mean": 96.8, + "median": 96.8, + "p10": 96.8, + "p25": 96.8, + "p75": 96.8, + "p90": 96.8, + "n": 1 + }, + { + "month": "2023-10", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 23.6, + "median": 23.6, + "p10": 23.6, + "p25": 23.6, + "p75": 23.6, + "p90": 23.6, + "n": 1 + }, + { + "month": "2024-03", + "mean": 61.4, + "median": 61.4, + "p10": 61.4, + "p25": 61.4, + "p75": 61.4, + "p90": 61.4, + "n": 1 + }, + { + "month": "2024-06", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1 + }, + { + "month": "2024-08", + "mean": 51.9, + "median": 51.9, + "p10": 51.9, + "p25": 51.9, + "p75": 51.9, + "p90": 51.9, + "n": 1 + }, + { + "month": "2024-11", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2025-03", + "mean": 21.2, + "median": 21.2, + "p10": 21.2, + "p25": 21.2, + "p75": 21.2, + "p90": 21.2, + "n": 1 + }, + { + "month": "2025-05", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2025-08", + "mean": 30.7, + "median": 30.7, + "p10": 30.7, + "p25": 30.7, + "p75": 30.7, + "p90": 30.7, + "n": 1 + }, + { + "month": "2025-09", + "mean": 37.1, + "median": 36.6, + "p10": 32.1, + "p25": 34.2, + "p75": 40.1, + "p90": 42.2, + "n": 5 + }, + { + "month": "2025-10", + "mean": 36.3, + "median": 36.6, + "p10": 31.6, + "p25": 33.0, + "p75": 38.9, + "p90": 41.1, + "n": 5 + }, + { + "month": "2025-11", + "mean": 41.8, + "median": 42.5, + "p10": 35.4, + "p25": 38.9, + "p75": 44.8, + "p90": 47.7, + "n": 5 + }, + { + "month": "2025-12", + "mean": 37.1, + "median": 37.8, + "p10": 30.2, + "p25": 33.0, + "p75": 41.3, + "p90": 43.4, + "n": 5 + }, + { + "month": "2026-01", + "mean": 42.5, + "median": 41.3, + "p10": 36.1, + "p25": 38.9, + "p75": 47.2, + "p90": 49.3, + "n": 5 + }, + { + "month": "2026-02", + "mean": 37.8, + "median": 36.6, + "p10": 32.1, + "p25": 34.2, + "p75": 40.1, + "p90": 44.4, + "n": 5 + }, + { + "month": "2026-03", + "mean": 33.0, + "median": 33.0, + "p10": 27.8, + "p25": 30.7, + "p75": 36.6, + "p90": 38.0, + "n": 5 + }, + { + "month": "2026-04", + "mean": 42.5, + "median": 42.5, + "p10": 37.5, + "p25": 38.9, + "p75": 44.8, + "p90": 47.7, + "n": 5 + }, + { + "month": "2026-05", + "mean": 37.5, + "median": 37.8, + "p10": 31.2, + "p25": 35.4, + "p75": 41.3, + "p90": 43.4, + "n": 5 + } + ], + "stats": { + "n": 63, + "mean": 39.4, + "median": 38.9, + "std": 11.4, + "min": 5.9, + "max": 96.8, + "p25": 33.0, + "p75": 44.8, + "p85": 47.2, + "p95": 56.6 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 96.8, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000081", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000081", + "first_gr_date": "2025-08-29", + "days_vs_promised": -1, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000082", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000082", + "first_gr_date": "2025-09-03", + "days_vs_promised": -2, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000080", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000080", + "first_gr_date": "2025-09-08", + "days_vs_promised": -2, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000083", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000083", + "first_gr_date": "2025-09-16", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000084", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000084", + "first_gr_date": "2025-10-01", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000086", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000086", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000088", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000088", + "first_gr_date": "2025-10-14", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000085", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000085", + "first_gr_date": "2025-10-19", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000087", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000087", + "first_gr_date": "2025-10-22", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000089", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000089", + "first_gr_date": "2025-11-01", + "days_vs_promised": -1, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000090", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000090", + "first_gr_date": "2025-11-06", + "days_vs_promised": -1, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000093", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000093", + "first_gr_date": "2025-11-23", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000094", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000094", + "first_gr_date": "2025-11-25", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000091", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000091", + "first_gr_date": "2025-11-30", + "days_vs_promised": -2, + "lead_time_days": 47 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000092", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000092", + "first_gr_date": "2025-12-07", + "days_vs_promised": -1, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000095", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000095", + "first_gr_date": "2025-12-20", + "days_vs_promised": -3, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000099", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000099", + "first_gr_date": "2025-12-27", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000096", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000096", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000098", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000098", + "first_gr_date": "2025-12-28", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000097", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000097", + "first_gr_date": "2025-12-30", + "days_vs_promised": -1, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000101", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000101", + "first_gr_date": "2026-01-15", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000102", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000102", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000100", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000100", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000122", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000122", + "first_gr_date": "2026-02-04", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000104", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000104", + "first_gr_date": "2026-02-08", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000103", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000103", + "first_gr_date": "2026-02-13", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000105", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000105", + "first_gr_date": "2026-02-23", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000125", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000125", + "first_gr_date": "2026-02-24", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000123", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000123", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000107", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000107", + "first_gr_date": "2026-03-02", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000124", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000124", + "first_gr_date": "2026-03-07", + "days_vs_promised": -3, + "lead_time_days": 37 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000106", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000106", + "first_gr_date": "2026-03-13", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000126", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000126", + "first_gr_date": "2026-03-14", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000127", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000127", + "first_gr_date": "2026-03-23", + "days_vs_promised": -1, + "lead_time_days": 34 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000108", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000108", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000128", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000128", + "first_gr_date": "2026-03-24", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000110", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000110", + "first_gr_date": "2026-03-25", + "days_vs_promised": -2, + "lead_time_days": 29 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000109", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000109", + "first_gr_date": "2026-04-06", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000129", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000129", + "first_gr_date": "2026-04-08", + "days_vs_promised": -3, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000114", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000114", + "first_gr_date": "2026-04-11", + "days_vs_promised": -2, + "lead_time_days": 19 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000111", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000111", + "first_gr_date": "2026-04-12", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000112", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000112", + "first_gr_date": "2026-04-13", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000130", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000130", + "first_gr_date": "2026-04-17", + "days_vs_promised": 0, + "lead_time_days": 39 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000115", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000115", + "first_gr_date": "2026-04-23", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000134", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000134", + "first_gr_date": "2026-04-30", + "days_vs_promised": -3, + "lead_time_days": 24 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000113", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000113", + "first_gr_date": "2026-05-01", + "days_vs_promised": -3, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000131", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000131", + "first_gr_date": "2026-05-01", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000117", + "po_item": "00030", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000117", + "first_gr_date": "2026-05-05", + "days_vs_promised": 0, + "lead_time_days": 20 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000136", + "po_item": "00050", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000136", + "first_gr_date": "2026-05-08", + "days_vs_promised": -2, + "lead_time_days": 18 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000132", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000132", + "first_gr_date": "2026-05-09", + "days_vs_promised": -2, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000133", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000133", + "first_gr_date": "2026-05-13", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000135", + "po_item": "00040", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000135", + "first_gr_date": "2026-05-18", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000116", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000116", + "first_gr_date": "2026-05-21", + "days_vs_promised": 0, + "lead_time_days": 45 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000138", + "po_item": "00020", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000138", + "first_gr_date": "2026-05-28", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000118", + "po_item": "00040", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000118", + "first_gr_date": "2026-05-31", + "days_vs_promised": -1, + "lead_time_days": 41 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000139", + "po_item": "00030", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000139", + "first_gr_date": "2026-05-31", + "days_vs_promised": -3, + "lead_time_days": 17 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000137", + "po_item": "00010", + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000137", + "first_gr_date": "2026-06-01", + "days_vs_promised": 0, + "lead_time_days": 33 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000120", + "po_item": "00010", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000120", + "first_gr_date": "2026-06-05", + "days_vs_promised": -3, + "lead_time_days": 30 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000119", + "po_item": "00050", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000119", + "first_gr_date": "2026-06-17", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_lowland_robusta", + "po_number": "4500000121", + "po_item": "00020", + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000121", + "first_gr_date": "2026-06-19", + "days_vs_promised": 0, + "lead_time_days": 37 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 18, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0004", + "name": "Riverbend Reliable Supply" + }, + "vendors": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "n_lines": 42, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "n_lines": 18, + "n_late": 0, + "on_time_pct": 100.0, + "in_full_pct": 100.0, + "otif_pct": 100.0, + "mean_days_late_all": 0, + "mean_days_late_when_late": null, + "median_days_late_when_late": null, + "max_days_late": 0, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 0.0, + "ge_3d_pct": 0.0, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [], + "coverage_pct": 100.0, + "n_lines": 60, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000080", + "po_item": "00010", + "po_date": "2025-07-29", + "promised_date": "2025-09-10", + "first_gr_date": "2025-09-08", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000081", + "po_item": "00020", + "po_date": "2025-08-07", + "promised_date": "2025-08-30", + "first_gr_date": "2025-08-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000082", + "po_item": "00030", + "po_date": "2025-08-11", + "promised_date": "2025-09-05", + "first_gr_date": "2025-09-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000083", + "po_item": "00040", + "po_date": "2025-08-19", + "promised_date": "2025-09-16", + "first_gr_date": "2025-09-16", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000084", + "po_item": "00050", + "po_date": "2025-08-27", + "promised_date": "2025-10-02", + "first_gr_date": "2025-10-01", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000085", + "po_item": "00010", + "po_date": "2025-09-04", + "promised_date": "2025-10-21", + "first_gr_date": "2025-10-19", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000086", + "po_item": "00020", + "po_date": "2025-09-10", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000087", + "po_item": "00030", + "po_date": "2025-09-15", + "promised_date": "2025-10-23", + "first_gr_date": "2025-10-22", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000088", + "po_item": "00040", + "po_date": "2025-09-22", + "promised_date": "2025-10-14", + "first_gr_date": "2025-10-14", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000089", + "po_item": "00050", + "po_date": "2025-09-29", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-01", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000090", + "po_item": "00010", + "po_date": "2025-10-08", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-06", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000091", + "po_item": "00020", + "po_date": "2025-10-14", + "promised_date": "2025-12-02", + "first_gr_date": "2025-11-30", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000092", + "po_item": "00030", + "po_date": "2025-10-20", + "promised_date": "2025-12-08", + "first_gr_date": "2025-12-07", + "days_late": -1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000093", + "po_item": "00040", + "po_date": "2025-10-27", + "promised_date": "2025-11-23", + "first_gr_date": "2025-11-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000094", + "po_item": "00050", + "po_date": "2025-11-04", + "promised_date": "2025-11-25", + "first_gr_date": "2025-11-25", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000095", + "po_item": "00010", + "po_date": "2025-11-11", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-20", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000096", + "po_item": "00020", + "po_date": "2025-11-20", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000097", + "po_item": "00030", + "po_date": "2025-11-25", + "promised_date": "2025-12-31", + "first_gr_date": "2025-12-30", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000098", + "po_item": "00040", + "po_date": "2025-12-03", + "promised_date": "2025-12-28", + "first_gr_date": "2025-12-28", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000099", + "po_item": "00050", + "po_date": "2025-12-09", + "promised_date": "2025-12-30", + "first_gr_date": "2025-12-27", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000100", + "po_item": "00010", + "po_date": "2025-12-17", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000101", + "po_item": "00020", + "po_date": "2025-12-23", + "promised_date": "2026-01-15", + "first_gr_date": "2026-01-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000102", + "po_item": "00030", + "po_date": "2025-12-31", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000103", + "po_item": "00040", + "po_date": "2026-01-06", + "promised_date": "2026-02-13", + "first_gr_date": "2026-02-13", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000104", + "po_item": "00050", + "po_date": "2026-01-14", + "promised_date": "2026-02-09", + "first_gr_date": "2026-02-08", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000105", + "po_item": "00010", + "po_date": "2026-01-19", + "promised_date": "2026-02-23", + "first_gr_date": "2026-02-23", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000106", + "po_item": "00020", + "po_date": "2026-01-27", + "promised_date": "2026-03-16", + "first_gr_date": "2026-03-13", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000107", + "po_item": "00030", + "po_date": "2026-02-05", + "promised_date": "2026-03-02", + "first_gr_date": "2026-03-02", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000108", + "po_item": "00040", + "po_date": "2026-02-12", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000109", + "po_item": "00050", + "po_date": "2026-02-17", + "promised_date": "2026-04-06", + "first_gr_date": "2026-04-06", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000110", + "po_item": "00010", + "po_date": "2026-02-24", + "promised_date": "2026-03-27", + "first_gr_date": "2026-03-25", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000111", + "po_item": "00020", + "po_date": "2026-03-05", + "promised_date": "2026-04-15", + "first_gr_date": "2026-04-12", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000112", + "po_item": "00030", + "po_date": "2026-03-09", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-13", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000113", + "po_item": "00040", + "po_date": "2026-03-17", + "promised_date": "2026-05-04", + "first_gr_date": "2026-05-01", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000114", + "po_item": "00050", + "po_date": "2026-03-23", + "promised_date": "2026-04-13", + "first_gr_date": "2026-04-11", + "days_late": -2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000115", + "po_item": "00010", + "po_date": "2026-04-01", + "promised_date": "2026-04-23", + "first_gr_date": "2026-04-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000116", + "po_item": "00020", + "po_date": "2026-04-06", + "promised_date": "2026-05-21", + "first_gr_date": "2026-05-21", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000117", + "po_item": "00030", + "po_date": "2026-04-15", + "promised_date": "2026-05-05", + "first_gr_date": "2026-05-05", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000118", + "po_item": "00040", + "po_date": "2026-04-20", + "promised_date": "2026-06-01", + "first_gr_date": "2026-05-31", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000119", + "po_item": "00050", + "po_date": "2026-04-30", + "promised_date": "2026-06-17", + "first_gr_date": "2026-06-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000120", + "po_item": "00010", + "po_date": "2026-05-06", + "promised_date": "2026-06-08", + "first_gr_date": "2026-06-05", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0004", + "vendor_name": "Riverbend Reliable Supply", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000121", + "po_item": "00020", + "po_date": "2026-05-13", + "promised_date": "2026-06-19", + "first_gr_date": "2026-06-19", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000122", + "po_item": "00010", + "po_date": "2026-01-12", + "promised_date": "2026-02-04", + "first_gr_date": "2026-02-04", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000123", + "po_item": "00020", + "po_date": "2026-01-20", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000124", + "po_item": "00030", + "po_date": "2026-01-29", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-07", + "days_late": -3, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000125", + "po_item": "00040", + "po_date": "2026-02-02", + "promised_date": "2026-02-24", + "first_gr_date": "2026-02-24", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000126", + "po_item": "00050", + "po_date": "2026-02-09", + "promised_date": "2026-03-14", + "first_gr_date": "2026-03-14", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000127", + "po_item": "00010", + "po_date": "2026-02-17", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-23", + "days_late": -1, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000128", + "po_item": "00020", + "po_date": "2026-02-23", + "promised_date": "2026-03-24", + "first_gr_date": "2026-03-24", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000129", + "po_item": "00030", + "po_date": "2026-03-04", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-08", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000130", + "po_item": "00040", + "po_date": "2026-03-09", + "promised_date": "2026-04-17", + "first_gr_date": "2026-04-17", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000131", + "po_item": "00050", + "po_date": "2026-03-16", + "promised_date": "2026-05-01", + "first_gr_date": "2026-05-01", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000132", + "po_item": "00010", + "po_date": "2026-03-25", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000133", + "po_item": "00020", + "po_date": "2026-04-02", + "promised_date": "2026-05-13", + "first_gr_date": "2026-05-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000134", + "po_item": "00030", + "po_date": "2026-04-06", + "promised_date": "2026-05-03", + "first_gr_date": "2026-04-30", + "days_late": -3, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000135", + "po_item": "00040", + "po_date": "2026-04-15", + "promised_date": "2026-05-18", + "first_gr_date": "2026-05-18", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000136", + "po_item": "00050", + "po_date": "2026-04-20", + "promised_date": "2026-05-10", + "first_gr_date": "2026-05-08", + "days_late": -2, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000137", + "po_item": "00010", + "po_date": "2026-04-29", + "promised_date": "2026-06-01", + "first_gr_date": "2026-06-01", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000138", + "po_item": "00020", + "po_date": "2026-05-06", + "promised_date": "2026-05-28", + "first_gr_date": "2026-05-28", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0001", + "vendor_name": "Andes Highland Coffee Co.", + "matnr": "demo_lowland_robusta", + "material_name": "Lowland Robusta", + "po_number": "4500000139", + "po_item": "00030", + "po_date": "2026-05-14", + "promised_date": "2026-06-03", + "first_gr_date": "2026-05-31", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_washed_bourbon.json new file mode 100644 index 00000000000..e7ce8b6acd7 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/procurement_washed_bourbon.json @@ -0,0 +1,2251 @@ +{ + "id": "procurement_washed_bourbon", + "label": "Procurement: Washed Bourbon", + "type": "procurement", + "durations": [ + 41.3, 18.9, 73.2, 8.3, 47.2, 29.5, 56.6, 14.2, 35.4, 16.5, 35.4, 22.4, 26.0, + 27.1, 29.5, 27.1, 29.5, 31.9, 34.2, 36.6, 27.1, 29.5, 31.9, 34.2, 36.6, + 26.0, 28.3, 30.7, 33.0, 21.2, 33.0, 35.4, 37.8, 26.0, 28.3, 31.9, 35.4, + 22.4, 26.0, 27.1, 40.1, 27.1, 29.5, 31.9, 34.2, 23.6, 27.1, 29.5, 31.9, + 34.2, 23.6, 26.0, 28.3, 30.7, 33.0 + ], + "observations": [ + { + "date": "2022-05-03", + "value": 41.3 + }, + { + "date": "2022-10-18", + "value": 18.9 + }, + { + "date": "2023-01-24", + "value": 73.2 + }, + { + "date": "2023-06-15", + "value": 8.3 + }, + { + "date": "2023-09-28", + "value": 47.2 + }, + { + "date": "2024-02-12", + "value": 29.5 + }, + { + "date": "2024-05-07", + "value": 56.6 + }, + { + "date": "2024-09-19", + "value": 14.2 + }, + { + "date": "2025-02-04", + "value": 35.4 + }, + { + "date": "2025-06-10", + "value": 16.5 + }, + { + "date": "2025-09-06", + "value": 35.4 + }, + { + "date": "2025-09-12", + "value": 22.4 + }, + { + "date": "2025-09-18", + "value": 26.0 + }, + { + "date": "2025-09-24", + "value": 27.1 + }, + { + "date": "2025-09-30", + "value": 29.5 + }, + { + "date": "2025-10-04", + "value": 27.1 + }, + { + "date": "2025-10-10", + "value": 29.5 + }, + { + "date": "2025-10-16", + "value": 31.9 + }, + { + "date": "2025-10-22", + "value": 34.2 + }, + { + "date": "2025-10-28", + "value": 36.6 + }, + { + "date": "2025-11-05", + "value": 27.1 + }, + { + "date": "2025-11-11", + "value": 29.5 + }, + { + "date": "2025-11-17", + "value": 31.9 + }, + { + "date": "2025-11-23", + "value": 34.2 + }, + { + "date": "2025-11-29", + "value": 36.6 + }, + { + "date": "2025-12-06", + "value": 26.0 + }, + { + "date": "2025-12-12", + "value": 28.3 + }, + { + "date": "2025-12-18", + "value": 30.7 + }, + { + "date": "2025-12-24", + "value": 33.0 + }, + { + "date": "2025-12-30", + "value": 21.2 + }, + { + "date": "2026-01-04", + "value": 33.0 + }, + { + "date": "2026-01-10", + "value": 35.4 + }, + { + "date": "2026-01-16", + "value": 37.8 + }, + { + "date": "2026-01-22", + "value": 26.0 + }, + { + "date": "2026-01-28", + "value": 28.3 + }, + { + "date": "2026-02-05", + "value": 31.9 + }, + { + "date": "2026-02-11", + "value": 35.4 + }, + { + "date": "2026-02-17", + "value": 22.4 + }, + { + "date": "2026-02-23", + "value": 26.0 + }, + { + "date": "2026-02-29", + "value": 27.1 + }, + { + "date": "2026-03-06", + "value": 40.1 + }, + { + "date": "2026-03-12", + "value": 27.1 + }, + { + "date": "2026-03-18", + "value": 29.5 + }, + { + "date": "2026-03-24", + "value": 31.9 + }, + { + "date": "2026-03-30", + "value": 34.2 + }, + { + "date": "2026-04-04", + "value": 23.6 + }, + { + "date": "2026-04-10", + "value": 27.1 + }, + { + "date": "2026-04-16", + "value": 29.5 + }, + { + "date": "2026-04-22", + "value": 31.9 + }, + { + "date": "2026-04-28", + "value": 34.2 + }, + { + "date": "2026-05-05", + "value": 23.6 + }, + { + "date": "2026-05-11", + "value": 26.0 + }, + { + "date": "2026-05-17", + "value": 28.3 + }, + { + "date": "2026-05-23", + "value": 30.7 + }, + { + "date": "2026-05-29", + "value": 33.0 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2022-10", + "mean": 18.9, + "median": 18.9, + "p10": 18.9, + "p25": 18.9, + "p75": 18.9, + "p90": 18.9, + "n": 1 + }, + { + "month": "2023-01", + "mean": 73.2, + "median": 73.2, + "p10": 73.2, + "p25": 73.2, + "p75": 73.2, + "p90": 73.2, + "n": 1 + }, + { + "month": "2023-06", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-09", + "mean": 47.2, + "median": 47.2, + "p10": 47.2, + "p25": 47.2, + "p75": 47.2, + "p90": 47.2, + "n": 1 + }, + { + "month": "2024-02", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 56.6, + "median": 56.6, + "p10": 56.6, + "p25": 56.6, + "p75": 56.6, + "p90": 56.6, + "n": 1 + }, + { + "month": "2024-09", + "mean": 14.2, + "median": 14.2, + "p10": 14.2, + "p25": 14.2, + "p75": 14.2, + "p90": 14.2, + "n": 1 + }, + { + "month": "2025-02", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2025-06", + "mean": 16.5, + "median": 16.5, + "p10": 16.5, + "p25": 16.5, + "p75": 16.5, + "p90": 16.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 28.1, + "median": 27.1, + "p10": 23.8, + "p25": 26.0, + "p75": 29.5, + "p90": 33.0, + "n": 5 + }, + { + "month": "2025-10", + "mean": 31.9, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 35.6, + "n": 5 + }, + { + "month": "2025-11", + "mean": 31.9, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 35.6, + "n": 5 + }, + { + "month": "2025-12", + "mean": 27.8, + "median": 28.3, + "p10": 23.1, + "p25": 26.0, + "p75": 30.7, + "p90": 32.1, + "n": 5 + }, + { + "month": "2026-01", + "mean": 32.1, + "median": 33.0, + "p10": 26.9, + "p25": 28.3, + "p75": 35.4, + "p90": 36.8, + "n": 5 + }, + { + "month": "2026-02", + "mean": 28.6, + "median": 27.1, + "p10": 23.8, + "p25": 26.0, + "p75": 31.9, + "p90": 34.0, + "n": 5 + }, + { + "month": "2026-03", + "mean": 32.6, + "median": 31.9, + "p10": 28.1, + "p25": 29.5, + "p75": 34.2, + "p90": 37.8, + "n": 5 + }, + { + "month": "2026-04", + "mean": 29.3, + "median": 29.5, + "p10": 25.0, + "p25": 27.1, + "p75": 31.9, + "p90": 33.3, + "n": 5 + }, + { + "month": "2026-05", + "mean": 28.3, + "median": 28.3, + "p10": 24.5, + "p25": 26.0, + "p75": 30.7, + "p90": 32.1, + "n": 5 + } + ], + "stats": { + "n": 55, + "mean": 30.8, + "median": 29.5, + "std": 8.0, + "min": 8.3, + "max": 73.2, + "p25": 26.0, + "p75": 34.2, + "p85": 35.4, + "p95": 41.3 + }, + "plifz": 7, + "plifz_note": null, + "pct_exceeding_plifz": 98.2, + "annotations": [], + "cost": null, + "detail_rows": { + "columns": [ + { + "key": "matnr", + "sap_field": "MATNR", + "sap_table": "EKPO", + "label": "Material", + "unit": null + }, + { + "key": "po_number", + "sap_field": "EBELN", + "sap_table": "EKKO", + "label": "PO Number", + "unit": null + }, + { + "key": "po_item", + "sap_field": "EBELP", + "sap_table": "EKPO", + "label": "PO Item", + "unit": null + }, + { + "key": "vendor_id", + "sap_field": "LIFNR", + "sap_table": "EKKO", + "label": "Vendor (LIFNR)", + "unit": null + }, + { + "key": "vendor_name", + "sap_field": "NAME1", + "sap_table": "LFA1", + "label": "Vendor Name", + "unit": null + }, + { + "key": "po_date", + "sap_field": "BEDAT", + "sap_table": "EKKO", + "label": "PO Date", + "unit": null + }, + { + "key": "promised_date", + "sap_field": "EINDT", + "sap_table": "EKET", + "label": "Promised Date", + "unit": null + }, + { + "key": "sched_qty", + "sap_field": "MENGE", + "sap_table": "EKET", + "label": "Scheduled Qty", + "unit": null + }, + { + "key": "gr_qty_to_date", + "sap_field": "WEMNG", + "sap_table": "EKET", + "label": "GR Qty (to date)", + "unit": null + }, + { + "key": "gr_mblnr", + "sap_field": "MBLNR", + "sap_table": "MSEG", + "label": "Goods Receipt Document", + "unit": null + }, + { + "key": "first_gr_date", + "sap_field": "BUDAT", + "sap_table": "MKPF", + "label": "Goods Receipt Date", + "unit": null + }, + { + "key": "days_vs_promised", + "sap_field": null, + "sap_table": null, + "label": "Days vs Promised", + "unit": "d" + }, + { + "key": "lead_time_days", + "sap_field": null, + "sap_table": null, + "label": "Lead Time (days)", + "unit": "d" + } + ], + "rows": [ + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000142", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000142", + "first_gr_date": "2025-10-29", + "days_vs_promised": 0, + "lead_time_days": 30 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000141", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000141", + "first_gr_date": "2025-11-02", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000140", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000140", + "first_gr_date": "2025-11-07", + "days_vs_promised": 24, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000143", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000143", + "first_gr_date": "2025-11-07", + "days_vs_promised": 0, + "lead_time_days": 29 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000144", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000144", + "first_gr_date": "2025-11-10", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000146", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000146", + "first_gr_date": "2025-12-03", + "days_vs_promised": -2, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000145", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000145", + "first_gr_date": "2025-12-11", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000148", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000148", + "first_gr_date": "2025-12-21", + "days_vs_promised": 0, + "lead_time_days": 41 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000147", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000147", + "first_gr_date": "2025-12-23", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000150", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000150", + "first_gr_date": "2026-01-06", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000149", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000149", + "first_gr_date": "2026-01-07", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000151", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000151", + "first_gr_date": "2026-01-13", + "days_vs_promised": -3, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000153", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000153", + "first_gr_date": "2026-01-13", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000155", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000155", + "first_gr_date": "2026-01-20", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000152", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000152", + "first_gr_date": "2026-01-26", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000154", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000154", + "first_gr_date": "2026-01-31", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000156", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000156", + "first_gr_date": "2026-02-14", + "days_vs_promised": -3, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000158", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000158", + "first_gr_date": "2026-02-15", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000157", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000157", + "first_gr_date": "2026-02-27", + "days_vs_promised": 0, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000159", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000159", + "first_gr_date": "2026-03-06", + "days_vs_promised": 0, + "lead_time_days": 38 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000176", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000176", + "first_gr_date": "2026-03-07", + "days_vs_promised": 0, + "lead_time_days": 23 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000160", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000160", + "first_gr_date": "2026-03-08", + "days_vs_promised": 0, + "lead_time_days": 34 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000175", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000175", + "first_gr_date": "2026-03-10", + "days_vs_promised": 0, + "lead_time_days": 35 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000178", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000178", + "first_gr_date": "2026-03-19", + "days_vs_promised": 0, + "lead_time_days": 22 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000161", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000161", + "first_gr_date": "2026-03-20", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000179", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000179", + "first_gr_date": "2026-03-29", + "days_vs_promised": -1, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000162", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000162", + "first_gr_date": "2026-04-01", + "days_vs_promised": 12, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000180", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000180", + "first_gr_date": "2026-04-02", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000177", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000177", + "first_gr_date": "2026-04-05", + "days_vs_promised": 2, + "lead_time_days": 47 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000165", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000165", + "first_gr_date": "2026-04-07", + "days_vs_promised": 0, + "lead_time_days": 28 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000164", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000164", + "first_gr_date": "2026-04-09", + "days_vs_promised": -1, + "lead_time_days": 37 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000163", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000163", + "first_gr_date": "2026-04-10", + "days_vs_promised": 0, + "lead_time_days": 46 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000166", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000166", + "first_gr_date": "2026-04-10", + "days_vs_promised": -1, + "lead_time_days": 24 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000167", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000167", + "first_gr_date": "2026-04-16", + "days_vs_promised": 0, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000181", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000181", + "first_gr_date": "2026-04-24", + "days_vs_promised": 0, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000182", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000182", + "first_gr_date": "2026-04-25", + "days_vs_promised": -3, + "lead_time_days": 32 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000183", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000183", + "first_gr_date": "2026-04-26", + "days_vs_promised": 0, + "lead_time_days": 25 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000168", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000168", + "first_gr_date": "2026-04-30", + "days_vs_promised": -1, + "lead_time_days": 31 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000171", + "po_item": "00020", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000171", + "first_gr_date": "2026-05-11", + "days_vs_promised": -3, + "lead_time_days": 18 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000185", + "po_item": "00010", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000185", + "first_gr_date": "2026-05-11", + "days_vs_promised": 0, + "lead_time_days": 27 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000184", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000184", + "first_gr_date": "2026-05-16", + "days_vs_promised": 0, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000169", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000169", + "first_gr_date": "2026-05-27", + "days_vs_promised": 0, + "lead_time_days": 50 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000170", + "po_item": "00010", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000170", + "first_gr_date": "2026-05-27", + "days_vs_promised": -2, + "lead_time_days": 43 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000174", + "po_item": "00050", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "gr_mblnr": "5000000174", + "first_gr_date": "2026-06-03", + "days_vs_promised": -2, + "lead_time_days": 21 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000172", + "po_item": "00030", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000172", + "first_gr_date": "2026-06-09", + "days_vs_promised": -2, + "lead_time_days": 40 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000186", + "po_item": "00020", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000186", + "first_gr_date": "2026-06-15", + "days_vs_promised": 5, + "lead_time_days": 55 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000189", + "po_item": "00050", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "gr_mblnr": "5000000189", + "first_gr_date": "2026-06-17", + "days_vs_promised": 1, + "lead_time_days": 36 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000187", + "po_item": "00030", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000187", + "first_gr_date": "2026-06-18", + "days_vs_promised": 0, + "lead_time_days": 49 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000188", + "po_item": "00040", + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "gr_mblnr": "5000000188", + "first_gr_date": "2026-06-21", + "days_vs_promised": 0, + "lead_time_days": 48 + }, + { + "matnr": "demo_washed_bourbon", + "po_number": "4500000173", + "po_item": "00040", + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "gr_mblnr": "5000000173", + "first_gr_date": "2026-07-02", + "days_vs_promised": 8, + "lead_time_days": 58 + } + ] + }, + "ref_date_col": "first_gr_date", + "n_batches": null, + "n_movements": 10, + "yield_data": null, + "consumption_data": null, + "supplier_otif": { + "primary_vendor": { + "id": "D0005", + "name": "Midland Mid-Tier Partners" + }, + "vendors": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "n_lines": 35, + "n_late": 4, + "on_time_pct": 88.6, + "in_full_pct": 100.0, + "otif_pct": 88.6, + "mean_days_late_all": 1.29, + "mean_days_late_when_late": 11.2, + "median_days_late_when_late": 10.0, + "max_days_late": 24, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 11.4, + "ge_3d_pct": 8.6, + "ge_7d_pct": 8.6, + "ge_14d_pct": 2.9 + } + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "n_lines": 15, + "n_late": 3, + "on_time_pct": 80.0, + "in_full_pct": 100.0, + "otif_pct": 80.0, + "mean_days_late_all": 0.53, + "mean_days_late_when_late": 2.7, + "median_days_late_when_late": 2, + "max_days_late": 5, + "fill_rate_pct": 100.0, + "late_buckets": { + "ge_1d_pct": 20.0, + "ge_3d_pct": 6.7, + "ge_7d_pct": 0.0, + "ge_14d_pct": 0.0 + } + } + ], + "worst_events": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0 + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0 + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0 + } + ], + "coverage_pct": 100.0, + "n_lines": 50, + "data_quality_note": "100% in-full across every line \u2014 likely WEMNG = MENGE is auto-stamped at goods receipt rather than measured. Treat the in-full metric as a data-entry artifact at this site.", + "tolerance_days": 0, + "under_tolerance_pct": 0.05, + "lines": [ + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000140", + "po_item": "00010", + "po_date": "2025-09-18", + "promised_date": "2025-10-14", + "first_gr_date": "2025-11-07", + "days_late": 24, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000141", + "po_item": "00020", + "po_date": "2025-09-23", + "promised_date": "2025-11-02", + "first_gr_date": "2025-11-02", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000142", + "po_item": "00030", + "po_date": "2025-09-29", + "promised_date": "2025-10-29", + "first_gr_date": "2025-10-29", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000143", + "po_item": "00040", + "po_date": "2025-10-09", + "promised_date": "2025-11-07", + "first_gr_date": "2025-11-07", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000144", + "po_item": "00050", + "po_date": "2025-10-13", + "promised_date": "2025-11-10", + "first_gr_date": "2025-11-10", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000145", + "po_item": "00010", + "po_date": "2025-10-22", + "promised_date": "2025-12-11", + "first_gr_date": "2025-12-11", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000146", + "po_item": "00020", + "po_date": "2025-10-28", + "promised_date": "2025-12-05", + "first_gr_date": "2025-12-03", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000147", + "po_item": "00030", + "po_date": "2025-11-03", + "promised_date": "2025-12-23", + "first_gr_date": "2025-12-23", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000148", + "po_item": "00040", + "po_date": "2025-11-10", + "promised_date": "2025-12-21", + "first_gr_date": "2025-12-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000149", + "po_item": "00050", + "po_date": "2025-11-18", + "promised_date": "2026-01-07", + "first_gr_date": "2026-01-07", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000150", + "po_item": "00010", + "po_date": "2025-11-24", + "promised_date": "2026-01-09", + "first_gr_date": "2026-01-06", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000151", + "po_item": "00020", + "po_date": "2025-12-01", + "promised_date": "2026-01-16", + "first_gr_date": "2026-01-13", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000152", + "po_item": "00030", + "po_date": "2025-12-08", + "promised_date": "2026-01-26", + "first_gr_date": "2026-01-26", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000153", + "po_item": "00040", + "po_date": "2025-12-16", + "promised_date": "2026-01-13", + "first_gr_date": "2026-01-13", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000154", + "po_item": "00050", + "po_date": "2025-12-22", + "promised_date": "2026-02-02", + "first_gr_date": "2026-01-31", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000155", + "po_item": "00010", + "po_date": "2025-12-29", + "promised_date": "2026-01-20", + "first_gr_date": "2026-01-20", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000156", + "po_item": "00020", + "po_date": "2026-01-07", + "promised_date": "2026-02-17", + "first_gr_date": "2026-02-14", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000157", + "po_item": "00030", + "po_date": "2026-01-15", + "promised_date": "2026-02-27", + "first_gr_date": "2026-02-27", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000158", + "po_item": "00040", + "po_date": "2026-01-21", + "promised_date": "2026-02-15", + "first_gr_date": "2026-02-15", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000159", + "po_item": "00050", + "po_date": "2026-01-27", + "promised_date": "2026-03-06", + "first_gr_date": "2026-03-06", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000160", + "po_item": "00010", + "po_date": "2026-02-02", + "promised_date": "2026-03-08", + "first_gr_date": "2026-03-08", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000161", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-20", + "days_late": 1, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000162", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-03-20", + "first_gr_date": "2026-04-01", + "days_late": 12, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000163", + "po_item": "00040", + "po_date": "2026-02-23", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000164", + "po_item": "00050", + "po_date": "2026-03-03", + "promised_date": "2026-04-10", + "first_gr_date": "2026-04-09", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000165", + "po_item": "00010", + "po_date": "2026-03-10", + "promised_date": "2026-04-07", + "first_gr_date": "2026-04-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000166", + "po_item": "00020", + "po_date": "2026-03-17", + "promised_date": "2026-04-11", + "first_gr_date": "2026-04-10", + "days_late": -1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000167", + "po_item": "00030", + "po_date": "2026-03-26", + "promised_date": "2026-04-16", + "first_gr_date": "2026-04-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000168", + "po_item": "00040", + "po_date": "2026-03-30", + "promised_date": "2026-05-01", + "first_gr_date": "2026-04-30", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000169", + "po_item": "00050", + "po_date": "2026-04-07", + "promised_date": "2026-05-27", + "first_gr_date": "2026-05-27", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000170", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-29", + "first_gr_date": "2026-05-27", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000171", + "po_item": "00020", + "po_date": "2026-04-23", + "promised_date": "2026-05-14", + "first_gr_date": "2026-05-11", + "days_late": -3, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000172", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-11", + "first_gr_date": "2026-06-09", + "days_late": -2, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000173", + "po_item": "00040", + "po_date": "2026-05-05", + "promised_date": "2026-06-24", + "first_gr_date": "2026-07-02", + "days_late": 8, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0005", + "vendor_name": "Midland Mid-Tier Partners", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000174", + "po_item": "00050", + "po_date": "2026-05-13", + "promised_date": "2026-06-05", + "first_gr_date": "2026-06-03", + "days_late": -2, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000175", + "po_item": "00010", + "po_date": "2026-02-03", + "promised_date": "2026-03-10", + "first_gr_date": "2026-03-10", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000176", + "po_item": "00020", + "po_date": "2026-02-12", + "promised_date": "2026-03-07", + "first_gr_date": "2026-03-07", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000177", + "po_item": "00030", + "po_date": "2026-02-17", + "promised_date": "2026-04-03", + "first_gr_date": "2026-04-05", + "days_late": 2, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000178", + "po_item": "00040", + "po_date": "2026-02-25", + "promised_date": "2026-03-19", + "first_gr_date": "2026-03-19", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000179", + "po_item": "00050", + "po_date": "2026-03-04", + "promised_date": "2026-03-30", + "first_gr_date": "2026-03-29", + "days_late": -1, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000180", + "po_item": "00010", + "po_date": "2026-03-12", + "promised_date": "2026-04-02", + "first_gr_date": "2026-04-02", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000181", + "po_item": "00020", + "po_date": "2026-03-19", + "promised_date": "2026-04-24", + "first_gr_date": "2026-04-24", + "days_late": 0, + "sched_qty": 500.0, + "gr_qty_to_date": 500.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000182", + "po_item": "00030", + "po_date": "2026-03-24", + "promised_date": "2026-04-28", + "first_gr_date": "2026-04-25", + "days_late": -3, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000183", + "po_item": "00040", + "po_date": "2026-04-01", + "promised_date": "2026-04-26", + "first_gr_date": "2026-04-26", + "days_late": 0, + "sched_qty": 200.0, + "gr_qty_to_date": 200.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000184", + "po_item": "00050", + "po_date": "2026-04-06", + "promised_date": "2026-05-16", + "first_gr_date": "2026-05-16", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000185", + "po_item": "00010", + "po_date": "2026-04-14", + "promised_date": "2026-05-11", + "first_gr_date": "2026-05-11", + "days_late": 0, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000186", + "po_item": "00020", + "po_date": "2026-04-21", + "promised_date": "2026-06-10", + "first_gr_date": "2026-06-15", + "days_late": 5, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000187", + "po_item": "00030", + "po_date": "2026-04-30", + "promised_date": "2026-06-18", + "first_gr_date": "2026-06-18", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000188", + "po_item": "00040", + "po_date": "2026-05-04", + "promised_date": "2026-06-21", + "first_gr_date": "2026-06-21", + "days_late": 0, + "sched_qty": 100.0, + "gr_qty_to_date": 100.0, + "on_time": true, + "in_full": true + }, + { + "vendor_id": "D0003", + "vendor_name": "Harbor City Coffee Importers", + "matnr": "demo_washed_bourbon", + "material_name": "Washed Bourbon", + "po_number": "4500000189", + "po_item": "00050", + "po_date": "2026-05-12", + "promised_date": "2026-06-16", + "first_gr_date": "2026-06-17", + "days_late": 1, + "sched_qty": 1000.0, + "gr_qty_to_date": 1000.0, + "on_time": false, + "in_full": true + } + ] + }, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_green_blend.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_green_blend.json new file mode 100644 index 00000000000..38dc72177a2 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_green_blend.json @@ -0,0 +1,924 @@ +{ + "id": "prod_duration_green_blend", + "label": "Production: Green Blend", + "type": "production", + "durations": [ + 3.5, 5.9, 2.4, 8.3, 4.7, 7.1, 3.5, 16.5, 4.7, 9.4, 3.5, 5.9, 1.2, 7.1, 3.5, + 4.7, 4.7, 4.7, 3.5, 4.7, 4.7, 4.7, 4.7, 5.9, 5.9, 5.9, 4.7, 5.9, 5.9, 3.5, + 4.7, 5.9, 3.5, 3.5, 5.9, 3.5, 4.7, 4.7, 3.5, 3.5, 4.7, 4.7, 4.7, 4.7, 5.9, + 5.9, 4.7, 4.7, 5.9, 5.9 + ], + "observations": [ + { + "date": "2022-04-18", + "value": 3.5 + }, + { + "date": "2022-07-05", + "value": 5.9 + }, + { + "date": "2022-10-12", + "value": 2.4 + }, + { + "date": "2023-01-20", + "value": 8.3 + }, + { + "date": "2023-04-15", + "value": 4.7 + }, + { + "date": "2023-07-28", + "value": 7.1 + }, + { + "date": "2023-10-05", + "value": 3.5 + }, + { + "date": "2024-01-12", + "value": 16.5 + }, + { + "date": "2024-04-22", + "value": 4.7 + }, + { + "date": "2024-07-10", + "value": 9.4 + }, + { + "date": "2024-10-18", + "value": 3.5 + }, + { + "date": "2025-01-25", + "value": 5.9 + }, + { + "date": "2025-05-08", + "value": 1.2 + }, + { + "date": "2025-08-15", + "value": 7.1 + }, + { + "date": "2025-09-04", + "value": 3.5 + }, + { + "date": "2025-09-10", + "value": 4.7 + }, + { + "date": "2025-09-16", + "value": 4.7 + }, + { + "date": "2025-09-22", + "value": 4.7 + }, + { + "date": "2025-10-05", + "value": 3.5 + }, + { + "date": "2025-10-11", + "value": 4.7 + }, + { + "date": "2025-10-17", + "value": 4.7 + }, + { + "date": "2025-10-23", + "value": 4.7 + }, + { + "date": "2025-11-06", + "value": 4.7 + }, + { + "date": "2025-11-12", + "value": 5.9 + }, + { + "date": "2025-11-18", + "value": 5.9 + }, + { + "date": "2025-11-24", + "value": 5.9 + }, + { + "date": "2025-12-04", + "value": 4.7 + }, + { + "date": "2025-12-10", + "value": 5.9 + }, + { + "date": "2025-12-16", + "value": 5.9 + }, + { + "date": "2025-12-22", + "value": 3.5 + }, + { + "date": "2026-01-05", + "value": 4.7 + }, + { + "date": "2026-01-11", + "value": 5.9 + }, + { + "date": "2026-01-17", + "value": 3.5 + }, + { + "date": "2026-01-23", + "value": 3.5 + }, + { + "date": "2026-02-06", + "value": 5.9 + }, + { + "date": "2026-02-12", + "value": 3.5 + }, + { + "date": "2026-02-18", + "value": 4.7 + }, + { + "date": "2026-02-24", + "value": 4.7 + }, + { + "date": "2026-03-04", + "value": 3.5 + }, + { + "date": "2026-03-10", + "value": 3.5 + }, + { + "date": "2026-03-16", + "value": 4.7 + }, + { + "date": "2026-03-22", + "value": 4.7 + }, + { + "date": "2026-04-05", + "value": 4.7 + }, + { + "date": "2026-04-11", + "value": 4.7 + }, + { + "date": "2026-04-17", + "value": 5.9 + }, + { + "date": "2026-04-23", + "value": 5.9 + }, + { + "date": "2026-05-06", + "value": 4.7 + }, + { + "date": "2026-05-12", + "value": 4.7 + }, + { + "date": "2026-05-18", + "value": 5.9 + }, + { + "date": "2026-05-24", + "value": 5.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-01", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-04", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-07", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2023-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 16.5, + "median": 16.5, + "p10": 16.5, + "p25": 16.5, + "p75": 16.5, + "p90": 16.5, + "n": 1 + }, + { + "month": "2024-04", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2024-10", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-01", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2025-05", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 5.7, + "median": 5.9, + "p10": 5.1, + "p25": 5.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2025-12", + "mean": 5.1, + "median": 5.3, + "p10": 3.9, + "p25": 4.5, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.5, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 5.1, + "p90": 5.5, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.7, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 5.1, + "p90": 5.5, + "n": 4 + }, + { + "month": "2026-03", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 5.3, + "median": 5.3, + "p10": 4.7, + "p25": 4.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + }, + { + "month": "2026-05", + "mean": 5.3, + "median": 5.3, + "p10": 4.7, + "p25": 4.7, + "p75": 5.9, + "p90": 5.9, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 5.1, + "median": 4.7, + "std": 1.8, + "min": 1.2, + "max": 16.5, + "p25": 3.5, + "p75": 5.9, + "p85": 5.9, + "p95": 7.1 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 10.0, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 50, + "n_movements": null, + "yield_data": { + "values": [ + 98.2, 99.5, 97.8, 100.2, 96.5, 99.0, 98.8, 97.2, 99.5, 100.8, 98.0, 97.5, + 99.2, 98.5, 98.4, 98.6, 98.9, 99.1, 98.3, 98.5, 98.8, 99.1, 99.0, 99.3, + 99.6, 98.2, 99.0, 99.3, 97.9, 98.2, 98.9, 97.6, 97.9, 98.1, 98.1, 98.4, + 98.6, 98.9, 98.1, 98.3, 98.5, 98.8, 98.8, 99.0, 99.3, 99.6, 98.7, 99.0, + 99.3, 97.9 + ], + "observations": [ + { + "date": "2022-04-21", + "value": 98.2 + }, + { + "date": "2022-07-10", + "value": 99.5 + }, + { + "date": "2022-10-14", + "value": 97.8 + }, + { + "date": "2023-01-27", + "value": 100.2 + }, + { + "date": "2023-04-19", + "value": 96.5 + }, + { + "date": "2023-08-03", + "value": 99.0 + }, + { + "date": "2023-10-08", + "value": 98.8 + }, + { + "date": "2024-01-26", + "value": 97.2 + }, + { + "date": "2024-04-26", + "value": 99.5 + }, + { + "date": "2024-07-18", + "value": 100.8 + }, + { + "date": "2024-10-21", + "value": 98.0 + }, + { + "date": "2025-01-30", + "value": 97.5 + }, + { + "date": "2025-05-09", + "value": 99.2 + }, + { + "date": "2025-08-21", + "value": 98.5 + }, + { + "date": "2025-09-05", + "value": 98.4 + }, + { + "date": "2025-09-11", + "value": 98.6 + }, + { + "date": "2025-09-17", + "value": 98.9 + }, + { + "date": "2025-09-23", + "value": 99.1 + }, + { + "date": "2025-10-06", + "value": 98.3 + }, + { + "date": "2025-10-12", + "value": 98.5 + }, + { + "date": "2025-10-18", + "value": 98.8 + }, + { + "date": "2025-10-24", + "value": 99.1 + }, + { + "date": "2025-11-04", + "value": 99.0 + }, + { + "date": "2025-11-10", + "value": 99.3 + }, + { + "date": "2025-11-16", + "value": 99.6 + }, + { + "date": "2025-11-22", + "value": 98.2 + }, + { + "date": "2025-12-05", + "value": 99.0 + }, + { + "date": "2025-12-11", + "value": 99.3 + }, + { + "date": "2025-12-17", + "value": 97.9 + }, + { + "date": "2025-12-23", + "value": 98.2 + }, + { + "date": "2026-01-06", + "value": 98.9 + }, + { + "date": "2026-01-12", + "value": 97.6 + }, + { + "date": "2026-01-18", + "value": 97.9 + }, + { + "date": "2026-01-24", + "value": 98.1 + }, + { + "date": "2026-02-04", + "value": 98.1 + }, + { + "date": "2026-02-10", + "value": 98.4 + }, + { + "date": "2026-02-16", + "value": 98.6 + }, + { + "date": "2026-02-22", + "value": 98.9 + }, + { + "date": "2026-03-05", + "value": 98.1 + }, + { + "date": "2026-03-11", + "value": 98.3 + }, + { + "date": "2026-03-17", + "value": 98.5 + }, + { + "date": "2026-03-23", + "value": 98.8 + }, + { + "date": "2026-04-06", + "value": 98.8 + }, + { + "date": "2026-04-12", + "value": 99.0 + }, + { + "date": "2026-04-18", + "value": 99.3 + }, + { + "date": "2026-04-24", + "value": 99.6 + }, + { + "date": "2026-05-04", + "value": 98.7 + }, + { + "date": "2026-05-10", + "value": 99.0 + }, + { + "date": "2026-05-16", + "value": 99.3 + }, + { + "date": "2026-05-22", + "value": 97.9 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-10", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 96.5, + "median": 96.5, + "p10": 96.5, + "p25": 96.5, + "p75": 96.5, + "p90": 96.5, + "n": 1 + }, + { + "month": "2023-08", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-10", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2024-01", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2024-04", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-07", + "mean": 100.8, + "median": 100.8, + "p10": 100.8, + "p25": 100.8, + "p75": 100.8, + "p90": 100.8, + "n": 1 + }, + { + "month": "2024-10", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2025-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2025-08", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 98.8, + "median": 98.8, + "p10": 98.5, + "p25": 98.6, + "p75": 99.0, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-10", + "mean": 98.7, + "median": 98.7, + "p10": 98.4, + "p25": 98.5, + "p75": 98.9, + "p90": 99.0, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.0, + "median": 99.2, + "p10": 98.4, + "p25": 98.8, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 98.6, + "median": 98.6, + "p10": 98.0, + "p25": 98.1, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.1, + "median": 98.0, + "p10": 97.7, + "p25": 97.8, + "p75": 98.3, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 98.5, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.7, + "p90": 98.8, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.4, + "median": 98.4, + "p10": 98.2, + "p25": 98.3, + "p75": 98.6, + "p90": 98.7, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 98.7, + "median": 98.9, + "p10": 98.1, + "p25": 98.5, + "p75": 99.1, + "p90": 99.2, + "n": 4 + } + ], + "stats": { + "n": 50, + "mean": 98.7, + "median": 98.8, + "std": 0.7, + "min": 96.5, + "max": 100.8, + "p25": 98.2, + "p75": 99.1, + "p85": 99.3, + "p95": 99.6 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_harbor_dark_roast.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_harbor_dark_roast.json new file mode 100644 index 00000000000..a30a8d3b432 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_duration_harbor_dark_roast.json @@ -0,0 +1,1148 @@ +{ + "id": "prod_duration_harbor_dark_roast", + "label": "Production: Harbor Dark Roast", + "type": "production", + "durations": [ + 2.4, 3.5, 1.2, 4.7, 2.4, 5.9, 3.5, 8.3, 2.4, 4.7, 1.2, 3.5, 11.8, 3.5, 2.4, + 5.9, 0.0, 4.7, 3.5, 2.4, 7.1, 3.5, 4.7, 4.7, 3.5, 3.5, 4.7, 2.4, 3.5, 3.5, + 2.4, 2.4, 3.5, 3.5, 3.5, 3.5, 3.5, 4.7, 3.5, 3.5, 3.5, 4.7, 4.7, 4.7, 4.7, + 3.5, 3.5, 4.7, 2.4, 3.5, 3.5, 2.4, 2.4, 3.5, 3.5, 3.5, 3.5, 3.5 + ], + "observations": [ + { + "date": "2022-05-20", + "value": 2.4 + }, + { + "date": "2022-06-10", + "value": 3.5 + }, + { + "date": "2022-07-15", + "value": 1.2 + }, + { + "date": "2022-08-22", + "value": 4.7 + }, + { + "date": "2022-10-05", + "value": 2.4 + }, + { + "date": "2022-11-18", + "value": 5.9 + }, + { + "date": "2023-01-10", + "value": 3.5 + }, + { + "date": "2023-03-25", + "value": 8.3 + }, + { + "date": "2023-05-12", + "value": 2.4 + }, + { + "date": "2023-07-08", + "value": 4.7 + }, + { + "date": "2023-09-15", + "value": 1.2 + }, + { + "date": "2023-11-22", + "value": 3.5 + }, + { + "date": "2024-01-18", + "value": 11.8 + }, + { + "date": "2024-03-08", + "value": 3.5 + }, + { + "date": "2024-05-15", + "value": 2.4 + }, + { + "date": "2024-07-22", + "value": 5.9 + }, + { + "date": "2024-09-10", + "value": 0.0 + }, + { + "date": "2024-11-05", + "value": 4.7 + }, + { + "date": "2025-01-15", + "value": 3.5 + }, + { + "date": "2025-03-20", + "value": 2.4 + }, + { + "date": "2025-05-28", + "value": 7.1 + }, + { + "date": "2025-08-05", + "value": 3.5 + }, + { + "date": "2025-09-05", + "value": 4.7 + }, + { + "date": "2025-09-11", + "value": 4.7 + }, + { + "date": "2025-09-17", + "value": 3.5 + }, + { + "date": "2025-09-23", + "value": 3.5 + }, + { + "date": "2025-10-06", + "value": 4.7 + }, + { + "date": "2025-10-12", + "value": 2.4 + }, + { + "date": "2025-10-18", + "value": 3.5 + }, + { + "date": "2025-10-24", + "value": 3.5 + }, + { + "date": "2025-11-04", + "value": 2.4 + }, + { + "date": "2025-11-10", + "value": 2.4 + }, + { + "date": "2025-11-16", + "value": 3.5 + }, + { + "date": "2025-11-22", + "value": 3.5 + }, + { + "date": "2025-12-05", + "value": 3.5 + }, + { + "date": "2025-12-11", + "value": 3.5 + }, + { + "date": "2025-12-17", + "value": 3.5 + }, + { + "date": "2025-12-23", + "value": 4.7 + }, + { + "date": "2026-01-06", + "value": 3.5 + }, + { + "date": "2026-01-12", + "value": 3.5 + }, + { + "date": "2026-01-18", + "value": 3.5 + }, + { + "date": "2026-01-24", + "value": 4.7 + }, + { + "date": "2026-02-04", + "value": 4.7 + }, + { + "date": "2026-02-10", + "value": 4.7 + }, + { + "date": "2026-02-16", + "value": 4.7 + }, + { + "date": "2026-02-22", + "value": 3.5 + }, + { + "date": "2026-03-05", + "value": 3.5 + }, + { + "date": "2026-03-11", + "value": 4.7 + }, + { + "date": "2026-03-17", + "value": 2.4 + }, + { + "date": "2026-03-23", + "value": 3.5 + }, + { + "date": "2026-04-06", + "value": 3.5 + }, + { + "date": "2026-04-12", + "value": 2.4 + }, + { + "date": "2026-04-18", + "value": 2.4 + }, + { + "date": "2026-04-24", + "value": 3.5 + }, + { + "date": "2026-05-04", + "value": 3.5 + }, + { + "date": "2026-05-10", + "value": 3.5 + }, + { + "date": "2026-05-16", + "value": 3.5 + }, + { + "date": "2026-05-22", + "value": 3.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-06", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2022-08", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2022-10", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-11", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2023-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2023-03", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2023-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-07", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-09", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 11.8, + "median": 11.8, + "p10": 11.8, + "p25": 11.8, + "p75": 11.8, + "p90": 11.8, + "n": 1 + }, + { + "month": "2024-03", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2024-09", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2024-11", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2025-05", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2025-08", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-09", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2025-11", + "mean": 2.9, + "median": 2.9, + "p10": 2.4, + "p25": 2.4, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-01", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-02", + "mean": 4.5, + "median": 4.7, + "p10": 3.9, + "p25": 4.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 2.9, + "median": 2.9, + "p10": 2.4, + "p25": 2.4, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 3.8, + "median": 3.5, + "std": 1.4, + "min": 0.0, + "max": 11.8, + "p25": 3.5, + "p75": 4.7, + "p85": 4.7, + "p95": 5.9 + }, + "plifz": 5, + "plifz_note": "DZEIT (in-house production days)", + "pct_exceeding_plifz": 5.2, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": 58, + "n_movements": null, + "yield_data": { + "values": [ + 99.0, 98.5, 99.8, 97.2, 99.5, 98.0, 100.2, 98.8, 99.2, 97.5, 99.0, 98.5, + 100.5, 99.2, 98.0, 97.8, 99.5, 98.2, 99.0, 98.8, 99.5, 97.0, 98.9, 99.1, + 99.4, 99.6, 98.8, 99.0, 99.3, 99.6, 99.5, 99.8, 100.1, 98.7, 99.5, 99.8, + 98.4, 98.7, 99.4, 98.1, 98.4, 98.6, 98.6, 98.9, 99.1, 99.4, 98.6, 98.8, + 99.0, 99.3, 99.3, 99.5, 99.8, 100.1, 99.2, 99.5, 99.8, 98.4 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 99.0 + }, + { + "date": "2022-06-13", + "value": 98.5 + }, + { + "date": "2022-07-16", + "value": 99.8 + }, + { + "date": "2022-08-26", + "value": 97.2 + }, + { + "date": "2022-10-07", + "value": 99.5 + }, + { + "date": "2022-11-23", + "value": 98.0 + }, + { + "date": "2023-01-13", + "value": 100.2 + }, + { + "date": "2023-04-01", + "value": 98.8 + }, + { + "date": "2023-05-14", + "value": 99.2 + }, + { + "date": "2023-07-12", + "value": 97.5 + }, + { + "date": "2023-09-16", + "value": 99.0 + }, + { + "date": "2023-11-25", + "value": 98.5 + }, + { + "date": "2024-01-28", + "value": 100.5 + }, + { + "date": "2024-03-11", + "value": 99.2 + }, + { + "date": "2024-05-17", + "value": 98.0 + }, + { + "date": "2024-07-27", + "value": 97.8 + }, + { + "date": "2024-09-10", + "value": 99.5 + }, + { + "date": "2024-11-09", + "value": 98.2 + }, + { + "date": "2025-01-18", + "value": 99.0 + }, + { + "date": "2025-03-22", + "value": 98.8 + }, + { + "date": "2025-06-03", + "value": 99.5 + }, + { + "date": "2025-08-08", + "value": 97.0 + }, + { + "date": "2025-09-05", + "value": 98.9 + }, + { + "date": "2025-09-11", + "value": 99.1 + }, + { + "date": "2025-09-17", + "value": 99.4 + }, + { + "date": "2025-09-23", + "value": 99.6 + }, + { + "date": "2025-10-06", + "value": 98.8 + }, + { + "date": "2025-10-12", + "value": 99.0 + }, + { + "date": "2025-10-18", + "value": 99.3 + }, + { + "date": "2025-10-24", + "value": 99.6 + }, + { + "date": "2025-11-04", + "value": 99.5 + }, + { + "date": "2025-11-10", + "value": 99.8 + }, + { + "date": "2025-11-16", + "value": 100.1 + }, + { + "date": "2025-11-22", + "value": 98.7 + }, + { + "date": "2025-12-05", + "value": 99.5 + }, + { + "date": "2025-12-11", + "value": 99.8 + }, + { + "date": "2025-12-17", + "value": 98.4 + }, + { + "date": "2025-12-23", + "value": 98.7 + }, + { + "date": "2026-01-06", + "value": 99.4 + }, + { + "date": "2026-01-12", + "value": 98.1 + }, + { + "date": "2026-01-18", + "value": 98.4 + }, + { + "date": "2026-01-24", + "value": 98.6 + }, + { + "date": "2026-02-04", + "value": 98.6 + }, + { + "date": "2026-02-10", + "value": 98.9 + }, + { + "date": "2026-02-16", + "value": 99.1 + }, + { + "date": "2026-02-22", + "value": 99.4 + }, + { + "date": "2026-03-05", + "value": 98.6 + }, + { + "date": "2026-03-11", + "value": 98.8 + }, + { + "date": "2026-03-17", + "value": 99.0 + }, + { + "date": "2026-03-23", + "value": 99.3 + }, + { + "date": "2026-04-06", + "value": 99.3 + }, + { + "date": "2026-04-12", + "value": 99.5 + }, + { + "date": "2026-04-18", + "value": 99.8 + }, + { + "date": "2026-04-24", + "value": 100.1 + }, + { + "date": "2026-05-04", + "value": 99.2 + }, + { + "date": "2026-05-10", + "value": 99.5 + }, + { + "date": "2026-05-16", + "value": 99.8 + }, + { + "date": "2026-05-22", + "value": 98.4 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2022-06", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2022-07", + "mean": 99.8, + "median": 99.8, + "p10": 99.8, + "p25": 99.8, + "p75": 99.8, + "p90": 99.8, + "n": 1 + }, + { + "month": "2022-08", + "mean": 97.2, + "median": 97.2, + "p10": 97.2, + "p25": 97.2, + "p75": 97.2, + "p90": 97.2, + "n": 1 + }, + { + "month": "2022-10", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2022-11", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2023-01", + "mean": 100.2, + "median": 100.2, + "p10": 100.2, + "p25": 100.2, + "p75": 100.2, + "p90": 100.2, + "n": 1 + }, + { + "month": "2023-04", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2023-05", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2023-07", + "mean": 97.5, + "median": 97.5, + "p10": 97.5, + "p25": 97.5, + "p75": 97.5, + "p90": 97.5, + "n": 1 + }, + { + "month": "2023-09", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2023-11", + "mean": 98.5, + "median": 98.5, + "p10": 98.5, + "p25": 98.5, + "p75": 98.5, + "p90": 98.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 100.5, + "median": 100.5, + "p10": 100.5, + "p25": 100.5, + "p75": 100.5, + "p90": 100.5, + "n": 1 + }, + { + "month": "2024-03", + "mean": 99.2, + "median": 99.2, + "p10": 99.2, + "p25": 99.2, + "p75": 99.2, + "p90": 99.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 98.0, + "median": 98.0, + "p10": 98.0, + "p25": 98.0, + "p75": 98.0, + "p90": 98.0, + "n": 1 + }, + { + "month": "2024-07", + "mean": 97.8, + "median": 97.8, + "p10": 97.8, + "p25": 97.8, + "p75": 97.8, + "p90": 97.8, + "n": 1 + }, + { + "month": "2024-09", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2024-11", + "mean": 98.2, + "median": 98.2, + "p10": 98.2, + "p25": 98.2, + "p75": 98.2, + "p90": 98.2, + "n": 1 + }, + { + "month": "2025-01", + "mean": 99.0, + "median": 99.0, + "p10": 99.0, + "p25": 99.0, + "p75": 99.0, + "p90": 99.0, + "n": 1 + }, + { + "month": "2025-03", + "mean": 98.8, + "median": 98.8, + "p10": 98.8, + "p25": 98.8, + "p75": 98.8, + "p90": 98.8, + "n": 1 + }, + { + "month": "2025-06", + "mean": 99.5, + "median": 99.5, + "p10": 99.5, + "p25": 99.5, + "p75": 99.5, + "p90": 99.5, + "n": 1 + }, + { + "month": "2025-08", + "mean": 97.0, + "median": 97.0, + "p10": 97.0, + "p25": 97.0, + "p75": 97.0, + "p90": 97.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 99.3, + "median": 99.3, + "p10": 99.0, + "p25": 99.1, + "p75": 99.5, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 99.2, + "median": 99.2, + "p10": 98.9, + "p25": 99.0, + "p75": 99.4, + "p90": 99.5, + "n": 4 + }, + { + "month": "2025-11", + "mean": 99.5, + "median": 99.7, + "p10": 98.9, + "p25": 99.3, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2025-12", + "mean": 99.1, + "median": 99.1, + "p10": 98.5, + "p25": 98.6, + "p75": 99.6, + "p90": 99.7, + "n": 4 + }, + { + "month": "2026-01", + "mean": 98.6, + "median": 98.5, + "p10": 98.2, + "p25": 98.3, + "p75": 98.8, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-02", + "mean": 99.0, + "median": 99.0, + "p10": 98.7, + "p25": 98.8, + "p75": 99.2, + "p90": 99.3, + "n": 4 + }, + { + "month": "2026-03", + "mean": 98.9, + "median": 98.9, + "p10": 98.7, + "p25": 98.8, + "p75": 99.1, + "p90": 99.2, + "n": 4 + }, + { + "month": "2026-04", + "mean": 99.7, + "median": 99.7, + "p10": 99.4, + "p25": 99.5, + "p75": 99.9, + "p90": 100.0, + "n": 4 + }, + { + "month": "2026-05", + "mean": 99.2, + "median": 99.4, + "p10": 98.6, + "p25": 99.0, + "p75": 99.6, + "p90": 99.7, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 99.0, + "median": 99.1, + "std": 0.7, + "min": 97.0, + "max": 100.5, + "p25": 98.6, + "p75": 99.5, + "p85": 99.7, + "p95": 100.1 + }, + "reference": 100.0 + }, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_to_qa_pla.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_to_qa_pla.json new file mode 100644 index 00000000000..bb5ec91a6e8 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/prod_to_qa_pla.json @@ -0,0 +1,581 @@ +{ + "id": "prod_to_qa_pla", + "label": "Production \u2192 QA Release (PL-A)", + "type": "qa_hold", + "durations": [ + 2.4, 1.2, 3.5, 2.4, 5.9, 2.4, 4.7, 3.5, 7.1, 2.4, 15.3, 3.5, 8.3, 1.2, 4.7, + 5.9, 2.4, 0.0, 3.5, 9.4, 2.4, 5.9, 2.4, 3.5, 3.5, 3.5, 3.5, 3.5, 4.7, 4.7, + 3.5, 3.5, 3.5, 4.7, 3.5, 3.5, 3.5, 2.4, 4.7, 4.7, 3.5, 3.5, 4.7, 2.4, 3.5, + 3.5, 3.5, 3.5, 3.5, 4.7, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5 + ], + "observations": [ + { + "date": "2022-05-22", + "value": 2.4 + }, + { + "date": "2022-06-13", + "value": 1.2 + }, + { + "date": "2022-07-16", + "value": 3.5 + }, + { + "date": "2022-08-26", + "value": 2.4 + }, + { + "date": "2022-10-07", + "value": 5.9 + }, + { + "date": "2022-11-23", + "value": 2.4 + }, + { + "date": "2023-01-13", + "value": 4.7 + }, + { + "date": "2023-04-01", + "value": 3.5 + }, + { + "date": "2023-05-14", + "value": 7.1 + }, + { + "date": "2023-07-12", + "value": 2.4 + }, + { + "date": "2023-09-16", + "value": 15.3 + }, + { + "date": "2023-11-25", + "value": 3.5 + }, + { + "date": "2024-01-28", + "value": 8.3 + }, + { + "date": "2024-03-11", + "value": 1.2 + }, + { + "date": "2024-05-17", + "value": 4.7 + }, + { + "date": "2024-07-27", + "value": 5.9 + }, + { + "date": "2024-09-10", + "value": 2.4 + }, + { + "date": "2024-11-09", + "value": 0.0 + }, + { + "date": "2025-01-18", + "value": 3.5 + }, + { + "date": "2025-03-22", + "value": 9.4 + }, + { + "date": "2025-06-03", + "value": 2.4 + }, + { + "date": "2025-08-08", + "value": 5.9 + }, + { + "date": "2025-09-04", + "value": 2.4 + }, + { + "date": "2025-09-10", + "value": 3.5 + }, + { + "date": "2025-09-16", + "value": 3.5 + }, + { + "date": "2025-09-22", + "value": 3.5 + }, + { + "date": "2025-10-05", + "value": 3.5 + }, + { + "date": "2025-10-11", + "value": 3.5 + }, + { + "date": "2025-10-17", + "value": 4.7 + }, + { + "date": "2025-10-23", + "value": 4.7 + }, + { + "date": "2025-11-06", + "value": 3.5 + }, + { + "date": "2025-11-12", + "value": 3.5 + }, + { + "date": "2025-11-18", + "value": 3.5 + }, + { + "date": "2025-11-24", + "value": 4.7 + }, + { + "date": "2025-12-04", + "value": 3.5 + }, + { + "date": "2025-12-10", + "value": 3.5 + }, + { + "date": "2025-12-16", + "value": 3.5 + }, + { + "date": "2025-12-22", + "value": 2.4 + }, + { + "date": "2026-01-05", + "value": 4.7 + }, + { + "date": "2026-01-11", + "value": 4.7 + }, + { + "date": "2026-01-17", + "value": 3.5 + }, + { + "date": "2026-01-23", + "value": 3.5 + }, + { + "date": "2026-02-06", + "value": 4.7 + }, + { + "date": "2026-02-12", + "value": 2.4 + }, + { + "date": "2026-02-18", + "value": 3.5 + }, + { + "date": "2026-02-24", + "value": 3.5 + }, + { + "date": "2026-03-04", + "value": 3.5 + }, + { + "date": "2026-03-10", + "value": 3.5 + }, + { + "date": "2026-03-16", + "value": 3.5 + }, + { + "date": "2026-03-22", + "value": 4.7 + }, + { + "date": "2026-04-05", + "value": 3.5 + }, + { + "date": "2026-04-11", + "value": 3.5 + }, + { + "date": "2026-04-17", + "value": 3.5 + }, + { + "date": "2026-04-23", + "value": 3.5 + }, + { + "date": "2026-05-06", + "value": 3.5 + }, + { + "date": "2026-05-12", + "value": 3.5 + }, + { + "date": "2026-05-18", + "value": 3.5 + }, + { + "date": "2026-05-24", + "value": 3.5 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-06", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2022-07", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2022-08", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2022-10", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2022-11", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-01", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2023-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2023-05", + "mean": 7.1, + "median": 7.1, + "p10": 7.1, + "p25": 7.1, + "p75": 7.1, + "p90": 7.1, + "n": 1 + }, + { + "month": "2023-07", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2023-09", + "mean": 15.3, + "median": 15.3, + "p10": 15.3, + "p25": 15.3, + "p75": 15.3, + "p90": 15.3, + "n": 1 + }, + { + "month": "2023-11", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2024-01", + "mean": 8.3, + "median": 8.3, + "p10": 8.3, + "p25": 8.3, + "p75": 8.3, + "p90": 8.3, + "n": 1 + }, + { + "month": "2024-03", + "mean": 1.2, + "median": 1.2, + "p10": 1.2, + "p25": 1.2, + "p75": 1.2, + "p90": 1.2, + "n": 1 + }, + { + "month": "2024-05", + "mean": 4.7, + "median": 4.7, + "p10": 4.7, + "p25": 4.7, + "p75": 4.7, + "p90": 4.7, + "n": 1 + }, + { + "month": "2024-07", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2024-09", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2024-11", + "mean": 0.0, + "median": 0.0, + "p10": 0.0, + "p25": 0.0, + "p75": 0.0, + "p90": 0.0, + "n": 1 + }, + { + "month": "2025-01", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 1 + }, + { + "month": "2025-03", + "mean": 9.4, + "median": 9.4, + "p10": 9.4, + "p25": 9.4, + "p75": 9.4, + "p90": 9.4, + "n": 1 + }, + { + "month": "2025-06", + "mean": 2.4, + "median": 2.4, + "p10": 2.4, + "p25": 2.4, + "p75": 2.4, + "p90": 2.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 5.9, + "median": 5.9, + "p10": 5.9, + "p25": 5.9, + "p75": 5.9, + "p90": 5.9, + "n": 1 + }, + { + "month": "2025-09", + "mean": 3.3, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2025-10", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2025-11", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2025-12", + "mean": 3.3, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-01", + "mean": 4.1, + "median": 4.1, + "p10": 3.5, + "p25": 3.5, + "p75": 4.7, + "p90": 4.7, + "n": 4 + }, + { + "month": "2026-02", + "mean": 3.5, + "median": 3.5, + "p10": 2.7, + "p25": 3.3, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-03", + "mean": 3.9, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.9, + "p90": 4.4, + "n": 4 + }, + { + "month": "2026-04", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + }, + { + "month": "2026-05", + "mean": 3.5, + "median": 3.5, + "p10": 3.5, + "p25": 3.5, + "p75": 3.5, + "p90": 3.5, + "n": 4 + } + ], + "stats": { + "n": 58, + "mean": 3.9, + "median": 3.5, + "std": 1.8, + "min": 0.0, + "max": 15.3, + "p25": 3.5, + "p75": 4.7, + "p85": 4.7, + "p95": 7.1 + }, + "plifz": 5, + "plifz_note": "WEBAZ (GR processing days)", + "pct_exceeding_plifz": 6.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": null, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_highland_arabica.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_highland_arabica.json new file mode 100644 index 00000000000..af15d77ef91 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_highland_arabica.json @@ -0,0 +1,689 @@ +{ + "id": "raw_dwell_highland_arabica", + "label": "Raw Material Dwell: Highland Arabica", + "type": "raw_material_dwell", + "durations": [ + 41.3, 73.2, 21.2, 103.8, 49.6, 64.9, 35.4, 85.0, 29.5, 56.6, 17.7, 112.1, + 153.4, 53.1, 44.8, 76.7, 26.0, 92.0, 5.9, 64.9, 47.2, 33.0, 100.3, 59.0, + 129.8, 37.8, 80.2, 53.1, 108.6, 23.6, 68.4, 41.3, 49.6, 88.5, 14.2, 56.6, + 70.8, 44.8, 57.8, 63.7, 40.1, 46.0, 49.6, 72.0, 48.4, 54.3, 57.8, 62.5, + 42.5, 48.4, 51.9, 56.6, 61.4, 42.5, 46.0, 50.7, 55.5, 60.2, 55.5, 59.0, + 63.7, 68.4, 46.0, 53.1, 57.8, 63.7, 40.1, 46.0, 66.1, 72.0, 48.4, 54.3, + 57.8, 66.1, 42.5, 48.4, 51.9, 56.6, 37.8, 42.5, 46.0, 50.7, 55.5 + ], + "observations": [ + { + "date": "2022-04-02", + "value": 41.3 + }, + { + "date": "2022-04-15", + "value": 73.2 + }, + { + "date": "2022-04-28", + "value": 21.2 + }, + { + "date": "2022-08-05", + "value": 103.8 + }, + { + "date": "2022-08-12", + "value": 49.6 + }, + { + "date": "2022-08-20", + "value": 64.9 + }, + { + "date": "2022-08-28", + "value": 35.4 + }, + { + "date": "2023-01-10", + "value": 85.0 + }, + { + "date": "2023-01-22", + "value": 29.5 + }, + { + "date": "2023-01-30", + "value": 56.6 + }, + { + "date": "2023-06-05", + "value": 17.7 + }, + { + "date": "2023-06-18", + "value": 112.1 + }, + { + "date": "2023-10-03", + "value": 153.4 + }, + { + "date": "2023-10-10", + "value": 53.1 + }, + { + "date": "2023-10-18", + "value": 44.8 + }, + { + "date": "2023-10-25", + "value": 76.7 + }, + { + "date": "2023-10-30", + "value": 26.0 + }, + { + "date": "2024-03-05", + "value": 92.0 + }, + { + "date": "2024-03-12", + "value": 5.9 + }, + { + "date": "2024-03-20", + "value": 64.9 + }, + { + "date": "2024-03-28", + "value": 47.2 + }, + { + "date": "2024-07-08", + "value": 33.0 + }, + { + "date": "2024-07-15", + "value": 100.3 + }, + { + "date": "2024-07-22", + "value": 59.0 + }, + { + "date": "2024-11-04", + "value": 129.8 + }, + { + "date": "2024-11-11", + "value": 37.8 + }, + { + "date": "2024-11-18", + "value": 80.2 + }, + { + "date": "2024-11-25", + "value": 53.1 + }, + { + "date": "2024-11-30", + "value": 108.6 + }, + { + "date": "2025-03-03", + "value": 23.6 + }, + { + "date": "2025-03-10", + "value": 68.4 + }, + { + "date": "2025-03-17", + "value": 41.3 + }, + { + "date": "2025-03-24", + "value": 49.6 + }, + { + "date": "2025-07-02", + "value": 88.5 + }, + { + "date": "2025-07-09", + "value": 14.2 + }, + { + "date": "2025-07-16", + "value": 56.6 + }, + { + "date": "2025-07-23", + "value": 70.8 + }, + { + "date": "2025-07-30", + "value": 44.8 + }, + { + "date": "2025-09-05", + "value": 57.8 + }, + { + "date": "2025-09-11", + "value": 63.7 + }, + { + "date": "2025-09-17", + "value": 40.1 + }, + { + "date": "2025-09-23", + "value": 46.0 + }, + { + "date": "2025-09-29", + "value": 49.6 + }, + { + "date": "2025-10-06", + "value": 72.0 + }, + { + "date": "2025-10-12", + "value": 48.4 + }, + { + "date": "2025-10-18", + "value": 54.3 + }, + { + "date": "2025-10-24", + "value": 57.8 + }, + { + "date": "2025-10-30", + "value": 62.5 + }, + { + "date": "2025-11-04", + "value": 42.5 + }, + { + "date": "2025-11-10", + "value": 48.4 + }, + { + "date": "2025-11-16", + "value": 51.9 + }, + { + "date": "2025-11-22", + "value": 56.6 + }, + { + "date": "2025-11-28", + "value": 61.4 + }, + { + "date": "2025-12-05", + "value": 42.5 + }, + { + "date": "2025-12-11", + "value": 46.0 + }, + { + "date": "2025-12-17", + "value": 50.7 + }, + { + "date": "2025-12-23", + "value": 55.5 + }, + { + "date": "2025-12-29", + "value": 60.2 + }, + { + "date": "2026-01-06", + "value": 55.5 + }, + { + "date": "2026-01-12", + "value": 59.0 + }, + { + "date": "2026-01-18", + "value": 63.7 + }, + { + "date": "2026-01-24", + "value": 68.4 + }, + { + "date": "2026-01-30", + "value": 46.0 + }, + { + "date": "2026-02-04", + "value": 53.1 + }, + { + "date": "2026-02-10", + "value": 57.8 + }, + { + "date": "2026-02-16", + "value": 63.7 + }, + { + "date": "2026-02-22", + "value": 40.1 + }, + { + "date": "2026-02-28", + "value": 46.0 + }, + { + "date": "2026-03-05", + "value": 66.1 + }, + { + "date": "2026-03-11", + "value": 72.0 + }, + { + "date": "2026-03-17", + "value": 48.4 + }, + { + "date": "2026-03-23", + "value": 54.3 + }, + { + "date": "2026-03-29", + "value": 57.8 + }, + { + "date": "2026-04-06", + "value": 66.1 + }, + { + "date": "2026-04-12", + "value": 42.5 + }, + { + "date": "2026-04-18", + "value": 48.4 + }, + { + "date": "2026-04-24", + "value": 51.9 + }, + { + "date": "2026-04-30", + "value": 56.6 + }, + { + "date": "2026-05-04", + "value": 37.8 + }, + { + "date": "2026-05-10", + "value": 42.5 + }, + { + "date": "2026-05-16", + "value": 46.0 + }, + { + "date": "2026-05-22", + "value": 50.7 + }, + { + "date": "2026-05-28", + "value": 55.5 + } + ], + "monthly": [ + { + "month": "2022-04", + "mean": 45.2, + "median": 41.3, + "p10": 25.3, + "p25": 31.3, + "p75": 57.2, + "p90": 66.8, + "n": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "mean": 63.5, + "median": 57.2, + "p10": 39.6, + "p25": 46.0, + "p75": 74.7, + "p90": 92.2, + "n": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "mean": 57.0, + "median": 56.6, + "p10": 34.9, + "p25": 43.1, + "p75": 70.8, + "p90": 79.3, + "n": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "mean": 64.9, + "median": 64.9, + "p10": 27.1, + "p25": 41.3, + "p75": 88.5, + "p90": 102.7, + "n": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "mean": 70.8, + "median": 53.1, + "p10": 33.5, + "p25": 44.8, + "p75": 76.7, + "p90": 122.7, + "n": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "mean": 52.5, + "median": 56.0, + "p10": 18.3, + "p25": 36.9, + "p75": 71.7, + "p90": 83.9, + "n": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "mean": 64.1, + "median": 59.0, + "p10": 38.2, + "p25": 46.0, + "p75": 79.6, + "p90": 92.0, + "n": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "mean": 81.9, + "median": 80.2, + "p10": 43.9, + "p25": 53.1, + "p75": 108.6, + "p90": 121.3, + "n": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "mean": 45.8, + "median": 45.4, + "p10": 28.9, + "p25": 36.9, + "p75": 54.3, + "p90": 62.8, + "n": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "mean": 55.0, + "median": 56.6, + "p10": 26.4, + "p25": 44.8, + "p75": 70.8, + "p90": 81.4, + "n": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "mean": 51.4, + "median": 49.6, + "p10": 42.5, + "p25": 46.0, + "p75": 57.8, + "p90": 61.4, + "n": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "mean": 59.0, + "median": 57.8, + "p10": 50.7, + "p25": 54.3, + "p75": 62.5, + "p90": 68.2, + "n": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "mean": 52.2, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "mean": 51.0, + "median": 50.7, + "p10": 43.9, + "p25": 46.0, + "p75": 55.5, + "p90": 58.3, + "n": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "mean": 58.5, + "median": 59.0, + "p10": 49.8, + "p25": 55.5, + "p75": 63.7, + "p90": 66.6, + "n": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "mean": 52.2, + "median": 53.1, + "p10": 42.5, + "p25": 46.0, + "p75": 57.8, + "p90": 61.4, + "n": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "mean": 59.7, + "median": 57.8, + "p10": 50.7, + "p25": 54.3, + "p75": 66.1, + "p90": 69.6, + "n": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "mean": 53.1, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 56.6, + "p90": 62.3, + "n": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "mean": 46.5, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 50.7, + "p90": 53.6, + "n": 5, + "total_kg_days": 827400.0 + } + ], + "stats": { + "n": 83, + "mean": 57.0, + "median": 54.3, + "std": 19.8, + "min": 5.9, + "max": 153.4, + "p25": 44.8, + "p75": 63.7, + "p85": 72.0, + "p95": 100.3 + }, + "plifz": 30, + "plifz_note": null, + "pct_exceeding_plifz": 89.2, + "annotations": [ + { + "date": "2023-09-01", + "label": "Supplier change for Highland Arabica" + } + ], + "cost": { + "unit_price": 3.776, + "currency": "CHF", + "mean_qty": 4200.0, + "monthly": [ + { + "month": "2022-04", + "n_events": 3, + "total_kg_days": 483000.0 + }, + { + "month": "2022-08", + "n_events": 4, + "total_kg_days": 903000.0 + }, + { + "month": "2023-01", + "n_events": 3, + "total_kg_days": 609000.0 + }, + { + "month": "2023-06", + "n_events": 2, + "total_kg_days": 462000.0 + }, + { + "month": "2023-10", + "n_events": 5, + "total_kg_days": 1260000.0 + }, + { + "month": "2024-03", + "n_events": 4, + "total_kg_days": 747600.0 + }, + { + "month": "2024-07", + "n_events": 3, + "total_kg_days": 684600.0 + }, + { + "month": "2024-11", + "n_events": 5, + "total_kg_days": 1457400.0 + }, + { + "month": "2025-03", + "n_events": 4, + "total_kg_days": 651000.0 + }, + { + "month": "2025-07", + "n_events": 5, + "total_kg_days": 978600.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 915600.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1050000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 907200.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1041600.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 928200.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1062600.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 945000.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 827400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 38, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_lowland_robusta.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_lowland_robusta.json new file mode 100644 index 00000000000..8e6796c4923 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_lowland_robusta.json @@ -0,0 +1,563 @@ +{ + "id": "raw_dwell_lowland_robusta", + "label": "Raw Material Dwell: Lowland Robusta", + "type": "raw_material_dwell", + "durations": [ + 33.0, 53.1, 14.2, 73.2, 38.9, 92.0, 23.6, 64.9, 9.4, 49.6, 76.7, 44.8, 17.7, + 85.0, 29.5, 56.6, 3.5, 100.3, 35.4, 64.9, 26.0, 47.2, 115.6, 21.2, 46.0, + 48.4, 53.1, 35.4, 40.1, 44.8, 48.4, 31.9, 35.4, 37.8, 44.8, 27.1, 31.9, + 34.2, 37.8, 33.0, 37.8, 40.1, 43.7, 47.2, 33.0, 36.6, 38.9, 42.5, 46.0, + 42.5, 46.0, 48.4, 53.1, 35.4, 41.3, 44.8, 48.4, 31.9, 35.4, 40.1, 44.8, + 27.1, 31.9, 34.2, 50.7, 33.0, 37.8, 40.1, 43.7 + ], + "observations": [ + { + "date": "2022-05-02", + "value": 33.0 + }, + { + "date": "2022-05-10", + "value": 53.1 + }, + { + "date": "2022-05-18", + "value": 14.2 + }, + { + "date": "2022-05-25", + "value": 73.2 + }, + { + "date": "2023-02-06", + "value": 38.9 + }, + { + "date": "2023-02-14", + "value": 92.0 + }, + { + "date": "2023-02-22", + "value": 23.6 + }, + { + "date": "2023-02-28", + "value": 64.9 + }, + { + "date": "2023-09-05", + "value": 9.4 + }, + { + "date": "2023-09-15", + "value": 49.6 + }, + { + "date": "2023-09-25", + "value": 76.7 + }, + { + "date": "2024-04-03", + "value": 44.8 + }, + { + "date": "2024-04-10", + "value": 17.7 + }, + { + "date": "2024-04-17", + "value": 85.0 + }, + { + "date": "2024-04-24", + "value": 29.5 + }, + { + "date": "2024-10-02", + "value": 56.6 + }, + { + "date": "2024-10-09", + "value": 3.5 + }, + { + "date": "2024-10-16", + "value": 100.3 + }, + { + "date": "2024-10-23", + "value": 35.4 + }, + { + "date": "2024-10-30", + "value": 64.9 + }, + { + "date": "2025-04-07", + "value": 26.0 + }, + { + "date": "2025-04-14", + "value": 47.2 + }, + { + "date": "2025-04-21", + "value": 115.6 + }, + { + "date": "2025-04-28", + "value": 21.2 + }, + { + "date": "2025-09-04", + "value": 46.0 + }, + { + "date": "2025-09-10", + "value": 48.4 + }, + { + "date": "2025-09-16", + "value": 53.1 + }, + { + "date": "2025-09-22", + "value": 35.4 + }, + { + "date": "2025-09-28", + "value": 40.1 + }, + { + "date": "2025-10-05", + "value": 44.8 + }, + { + "date": "2025-10-11", + "value": 48.4 + }, + { + "date": "2025-10-17", + "value": 31.9 + }, + { + "date": "2025-10-23", + "value": 35.4 + }, + { + "date": "2025-10-29", + "value": 37.8 + }, + { + "date": "2025-11-06", + "value": 44.8 + }, + { + "date": "2025-11-12", + "value": 27.1 + }, + { + "date": "2025-11-18", + "value": 31.9 + }, + { + "date": "2025-11-24", + "value": 34.2 + }, + { + "date": "2025-11-30", + "value": 37.8 + }, + { + "date": "2025-12-04", + "value": 33.0 + }, + { + "date": "2025-12-10", + "value": 37.8 + }, + { + "date": "2025-12-16", + "value": 40.1 + }, + { + "date": "2025-12-22", + "value": 43.7 + }, + { + "date": "2025-12-28", + "value": 47.2 + }, + { + "date": "2026-01-05", + "value": 33.0 + }, + { + "date": "2026-01-11", + "value": 36.6 + }, + { + "date": "2026-01-17", + "value": 38.9 + }, + { + "date": "2026-01-23", + "value": 42.5 + }, + { + "date": "2026-01-29", + "value": 46.0 + }, + { + "date": "2026-02-06", + "value": 42.5 + }, + { + "date": "2026-02-12", + "value": 46.0 + }, + { + "date": "2026-02-18", + "value": 48.4 + }, + { + "date": "2026-02-24", + "value": 53.1 + }, + { + "date": "2026-02-30", + "value": 35.4 + }, + { + "date": "2026-03-04", + "value": 41.3 + }, + { + "date": "2026-03-10", + "value": 44.8 + }, + { + "date": "2026-03-16", + "value": 48.4 + }, + { + "date": "2026-03-22", + "value": 31.9 + }, + { + "date": "2026-03-28", + "value": 35.4 + }, + { + "date": "2026-04-05", + "value": 40.1 + }, + { + "date": "2026-04-11", + "value": 44.8 + }, + { + "date": "2026-04-17", + "value": 27.1 + }, + { + "date": "2026-04-23", + "value": 31.9 + }, + { + "date": "2026-04-29", + "value": 34.2 + }, + { + "date": "2026-05-06", + "value": 50.7 + }, + { + "date": "2026-05-12", + "value": 33.0 + }, + { + "date": "2026-05-18", + "value": 37.8 + }, + { + "date": "2026-05-24", + "value": 40.1 + }, + { + "date": "2026-05-30", + "value": 43.7 + } + ], + "monthly": [ + { + "month": "2022-05", + "mean": 43.4, + "median": 43.1, + "p10": 19.8, + "p25": 28.3, + "p75": 58.2, + "p90": 67.1, + "n": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "mean": 54.9, + "median": 51.9, + "p10": 28.2, + "p25": 35.2, + "p75": 71.7, + "p90": 83.9, + "n": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "mean": 45.2, + "median": 49.6, + "p10": 17.5, + "p25": 29.5, + "p75": 63.1, + "p90": 71.3, + "n": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "mean": 44.2, + "median": 37.2, + "p10": 21.2, + "p25": 26.5, + "p75": 54.9, + "p90": 72.9, + "n": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "mean": 52.2, + "median": 56.6, + "p10": 16.3, + "p25": 35.4, + "p75": 64.9, + "p90": 86.1, + "n": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "mean": 52.5, + "median": 36.6, + "p10": 22.7, + "p25": 24.8, + "p75": 64.3, + "p90": 95.1, + "n": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "mean": 44.6, + "median": 46.0, + "p10": 37.3, + "p25": 40.1, + "p75": 48.4, + "p90": 51.2, + "n": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "mean": 39.6, + "median": 37.8, + "p10": 33.3, + "p25": 35.4, + "p75": 44.8, + "p90": 47.0, + "n": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "mean": 35.2, + "median": 34.2, + "p10": 29.0, + "p25": 31.9, + "p75": 37.8, + "p90": 42.0, + "n": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "mean": 40.4, + "median": 40.1, + "p10": 34.9, + "p25": 37.8, + "p75": 43.7, + "p90": 45.8, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "mean": 39.4, + "median": 38.9, + "p10": 34.5, + "p25": 36.6, + "p75": 42.5, + "p90": 44.6, + "n": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "mean": 45.1, + "median": 46.0, + "p10": 38.2, + "p25": 42.5, + "p75": 48.4, + "p90": 51.2, + "n": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "mean": 40.4, + "median": 41.3, + "p10": 33.3, + "p25": 35.4, + "p75": 44.8, + "p90": 47.0, + "n": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "mean": 35.6, + "median": 34.2, + "p10": 29.0, + "p25": 31.9, + "p75": 40.1, + "p90": 43.0, + "n": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "mean": 41.1, + "median": 40.1, + "p10": 34.9, + "p25": 37.8, + "p75": 43.7, + "p90": 47.9, + "n": 5, + "total_kg_days": 1131000.0 + } + ], + "stats": { + "n": 69, + "mean": 43.2, + "median": 40.1, + "std": 15.8, + "min": 3.5, + "max": 115.6, + "p25": 33.0, + "p75": 48.4, + "p85": 53.1, + "p95": 76.7 + }, + "plifz": 21, + "plifz_note": null, + "pct_exceeding_plifz": 91.3, + "annotations": [], + "cost": { + "unit_price": 2.124, + "currency": "CHF", + "mean_qty": 6500.0, + "monthly": [ + { + "month": "2022-05", + "n_events": 4, + "total_kg_days": 955500.0 + }, + { + "month": "2023-02", + "n_events": 4, + "total_kg_days": 1209000.0 + }, + { + "month": "2023-09", + "n_events": 3, + "total_kg_days": 747500.0 + }, + { + "month": "2024-04", + "n_events": 4, + "total_kg_days": 975000.0 + }, + { + "month": "2024-10", + "n_events": 5, + "total_kg_days": 1436500.0 + }, + { + "month": "2025-04", + "n_events": 4, + "total_kg_days": 1157000.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 1228500.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 1092000.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 968500.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 1085500.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 1241500.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 1111500.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 981500.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 1131000.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 42, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_washed_bourbon.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_washed_bourbon.json new file mode 100644 index 00000000000..e41d6beff8c --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/raw_dwell_washed_bourbon.json @@ -0,0 +1,567 @@ +{ + "id": "raw_dwell_washed_bourbon", + "label": "Raw Material Dwell: Washed Bourbon", + "type": "raw_material_dwell", + "durations": [ + 47.2, 26.0, 80.2, 4.7, 64.9, 135.7, 35.4, 73.2, 21.2, 100.3, 41.3, 85.0, + 11.8, 56.6, 112.1, 33.0, 61.4, 17.7, 92.0, 49.6, 9.4, 76.7, 38.9, 118.0, + 23.6, 48.4, 53.1, 56.6, 61.4, 40.1, 47.2, 51.9, 56.6, 35.4, 40.1, 59.0, + 63.7, 42.5, 48.4, 51.9, 59.0, 37.8, 42.5, 46.0, 50.7, 33.0, 37.8, 41.3, + 44.8, 49.6, 46.0, 48.4, 53.1, 56.6, 61.4, 43.7, 47.2, 51.9, 56.6, 35.4, + 55.5, 59.0, 63.7, 42.5, 48.4, 54.3, 59.0, 37.8, 42.5, 46.0 + ], + "observations": [ + { + "date": "2022-06-05", + "value": 47.2 + }, + { + "date": "2022-06-15", + "value": 26.0 + }, + { + "date": "2022-06-25", + "value": 80.2 + }, + { + "date": "2023-03-08", + "value": 4.7 + }, + { + "date": "2023-03-15", + "value": 64.9 + }, + { + "date": "2023-03-22", + "value": 135.7 + }, + { + "date": "2023-03-29", + "value": 35.4 + }, + { + "date": "2023-11-06", + "value": 73.2 + }, + { + "date": "2023-11-13", + "value": 21.2 + }, + { + "date": "2023-11-20", + "value": 100.3 + }, + { + "date": "2024-06-03", + "value": 41.3 + }, + { + "date": "2024-06-10", + "value": 85.0 + }, + { + "date": "2024-06-17", + "value": 11.8 + }, + { + "date": "2024-06-24", + "value": 56.6 + }, + { + "date": "2024-06-30", + "value": 112.1 + }, + { + "date": "2025-01-07", + "value": 33.0 + }, + { + "date": "2025-01-14", + "value": 61.4 + }, + { + "date": "2025-01-21", + "value": 17.7 + }, + { + "date": "2025-01-28", + "value": 92.0 + }, + { + "date": "2025-08-04", + "value": 49.6 + }, + { + "date": "2025-08-08", + "value": 9.4 + }, + { + "date": "2025-08-12", + "value": 76.7 + }, + { + "date": "2025-08-16", + "value": 38.9 + }, + { + "date": "2025-08-20", + "value": 118.0 + }, + { + "date": "2025-08-24", + "value": 23.6 + }, + { + "date": "2025-09-06", + "value": 48.4 + }, + { + "date": "2025-09-12", + "value": 53.1 + }, + { + "date": "2025-09-18", + "value": 56.6 + }, + { + "date": "2025-09-24", + "value": 61.4 + }, + { + "date": "2025-09-30", + "value": 40.1 + }, + { + "date": "2025-10-04", + "value": 47.2 + }, + { + "date": "2025-10-10", + "value": 51.9 + }, + { + "date": "2025-10-16", + "value": 56.6 + }, + { + "date": "2025-10-22", + "value": 35.4 + }, + { + "date": "2025-10-28", + "value": 40.1 + }, + { + "date": "2025-11-05", + "value": 59.0 + }, + { + "date": "2025-11-11", + "value": 63.7 + }, + { + "date": "2025-11-17", + "value": 42.5 + }, + { + "date": "2025-11-23", + "value": 48.4 + }, + { + "date": "2025-11-29", + "value": 51.9 + }, + { + "date": "2025-12-06", + "value": 59.0 + }, + { + "date": "2025-12-12", + "value": 37.8 + }, + { + "date": "2025-12-18", + "value": 42.5 + }, + { + "date": "2025-12-24", + "value": 46.0 + }, + { + "date": "2025-12-30", + "value": 50.7 + }, + { + "date": "2026-01-04", + "value": 33.0 + }, + { + "date": "2026-01-10", + "value": 37.8 + }, + { + "date": "2026-01-16", + "value": 41.3 + }, + { + "date": "2026-01-22", + "value": 44.8 + }, + { + "date": "2026-01-28", + "value": 49.6 + }, + { + "date": "2026-02-05", + "value": 46.0 + }, + { + "date": "2026-02-11", + "value": 48.4 + }, + { + "date": "2026-02-17", + "value": 53.1 + }, + { + "date": "2026-02-23", + "value": 56.6 + }, + { + "date": "2026-02-29", + "value": 61.4 + }, + { + "date": "2026-03-06", + "value": 43.7 + }, + { + "date": "2026-03-12", + "value": 47.2 + }, + { + "date": "2026-03-18", + "value": 51.9 + }, + { + "date": "2026-03-24", + "value": 56.6 + }, + { + "date": "2026-03-30", + "value": 35.4 + }, + { + "date": "2026-04-04", + "value": 55.5 + }, + { + "date": "2026-04-10", + "value": 59.0 + }, + { + "date": "2026-04-16", + "value": 63.7 + }, + { + "date": "2026-04-22", + "value": 42.5 + }, + { + "date": "2026-04-28", + "value": 48.4 + }, + { + "date": "2026-05-05", + "value": 54.3 + }, + { + "date": "2026-05-11", + "value": 59.0 + }, + { + "date": "2026-05-17", + "value": 37.8 + }, + { + "date": "2026-05-23", + "value": 42.5 + }, + { + "date": "2026-05-29", + "value": 46.0 + } + ], + "monthly": [ + { + "month": "2022-06", + "mean": 51.1, + "median": 47.2, + "p10": 30.2, + "p25": 36.6, + "p75": 63.7, + "p90": 73.6, + "n": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "mean": 60.2, + "median": 50.1, + "p10": 13.9, + "p25": 27.7, + "p75": 82.6, + "p90": 114.5, + "n": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "mean": 64.9, + "median": 73.2, + "p10": 31.6, + "p25": 47.2, + "p75": 86.7, + "p90": 94.9, + "n": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "mean": 61.4, + "median": 56.6, + "p10": 23.6, + "p25": 41.3, + "p75": 85.0, + "p90": 101.2, + "n": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "mean": 51.1, + "median": 47.2, + "p10": 22.3, + "p25": 29.3, + "p75": 69.0, + "p90": 82.8, + "n": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "mean": 52.7, + "median": 44.2, + "p10": 16.5, + "p25": 27.5, + "p75": 70.0, + "p90": 97.3, + "n": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "mean": 51.9, + "median": 53.1, + "p10": 43.4, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "mean": 46.3, + "median": 47.2, + "p10": 37.3, + "p25": 40.1, + "p75": 51.9, + "p90": 54.8, + "n": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "mean": 53.1, + "median": 51.9, + "p10": 44.8, + "p25": 48.4, + "p75": 59.0, + "p90": 61.8, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "mean": 47.2, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 50.7, + "p90": 55.7, + "n": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "mean": 41.3, + "median": 41.3, + "p10": 34.9, + "p25": 37.8, + "p75": 44.8, + "p90": 47.7, + "n": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "mean": 53.1, + "median": 53.1, + "p10": 47.0, + "p25": 48.4, + "p75": 56.6, + "p90": 59.5, + "n": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "mean": 47.0, + "median": 47.2, + "p10": 38.7, + "p25": 43.7, + "p75": 51.9, + "p90": 54.8, + "n": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "mean": 53.8, + "median": 55.5, + "p10": 44.8, + "p25": 48.4, + "p75": 59.0, + "p90": 61.8, + "n": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "mean": 47.9, + "median": 46.0, + "p10": 39.6, + "p25": 42.5, + "p75": 54.3, + "p90": 57.1, + "n": 5, + "total_kg_days": 568400.0 + } + ], + "stats": { + "n": 70, + "mean": 51.8, + "median": 48.4, + "std": 19.1, + "min": 4.7, + "max": 135.7, + "p25": 40.1, + "p75": 59.0, + "p85": 63.7, + "p95": 92.0 + }, + "plifz": 14, + "plifz_note": null, + "pct_exceeding_plifz": 95.7, + "annotations": [], + "cost": { + "unit_price": 6.49, + "currency": "CHF", + "mean_qty": 2800.0, + "monthly": [ + { + "month": "2022-06", + "n_events": 3, + "total_kg_days": 364000.0 + }, + { + "month": "2023-03", + "n_events": 4, + "total_kg_days": 571200.0 + }, + { + "month": "2023-11", + "n_events": 3, + "total_kg_days": 462000.0 + }, + { + "month": "2024-06", + "n_events": 5, + "total_kg_days": 728000.0 + }, + { + "month": "2025-01", + "n_events": 4, + "total_kg_days": 484400.0 + }, + { + "month": "2025-08", + "n_events": 6, + "total_kg_days": 750400.0 + }, + { + "month": "2025-09", + "n_events": 5, + "total_kg_days": 616000.0 + }, + { + "month": "2025-10", + "n_events": 5, + "total_kg_days": 548800.0 + }, + { + "month": "2025-11", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2025-12", + "n_events": 5, + "total_kg_days": 560000.0 + }, + { + "month": "2026-01", + "n_events": 5, + "total_kg_days": 490000.0 + }, + { + "month": "2026-02", + "n_events": 5, + "total_kg_days": 630000.0 + }, + { + "month": "2026-03", + "n_events": 5, + "total_kg_days": 557200.0 + }, + { + "month": "2026-04", + "n_events": 5, + "total_kg_days": 638400.0 + }, + { + "month": "2026-05", + "n_events": 5, + "total_kg_days": 568400.0 + } + ] + }, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 25, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/transit_pla_hub1.json b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/transit_pla_hub1.json new file mode 100644 index 00000000000..1d263f283b1 --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/2026-06-17.1/summit-medium-roast/steps/transit_pla_hub1.json @@ -0,0 +1,437 @@ +{ + "id": "transit_pla_hub1", + "label": "Transit PL-A \u2192 HUB-1", + "type": "transit", + "durations": [ + 33.0, 41.3, 26.0, 49.6, 35.4, 64.9, 29.5, 44.8, 17.7, 37.8, 33.0, 53.1, + 35.4, 26.0, 42.5, 44.8, 46.0, 30.7, 42.5, 27.1, 30.7, 31.9, 36.6, 38.9, + 31.9, 34.2, 37.8, 30.7, 34.2, 36.6, 38.9, 42.5, 46.0, 38.9, 42.5, 27.1, + 47.2, 31.9, 36.6, 28.3, 31.9, 34.2 + ], + "observations": [ + { + "date": "2022-07-20", + "value": 33.0 + }, + { + "date": "2022-11-30", + "value": 41.3 + }, + { + "date": "2023-03-15", + "value": 26.0 + }, + { + "date": "2023-07-10", + "value": 49.6 + }, + { + "date": "2023-10-25", + "value": 35.4 + }, + { + "date": "2024-02-08", + "value": 64.9 + }, + { + "date": "2024-05-20", + "value": 29.5 + }, + { + "date": "2024-08-12", + "value": 44.8 + }, + { + "date": "2024-11-05", + "value": 17.7 + }, + { + "date": "2025-01-22", + "value": 37.8 + }, + { + "date": "2025-04-10", + "value": 33.0 + }, + { + "date": "2025-06-18", + "value": 53.1 + }, + { + "date": "2025-07-15", + "value": 35.4 + }, + { + "date": "2025-08-05", + "value": 26.0 + }, + { + "date": "2025-09-05", + "value": 42.5 + }, + { + "date": "2025-09-10", + "value": 44.8 + }, + { + "date": "2025-09-11", + "value": 46.0 + }, + { + "date": "2025-09-17", + "value": 30.7 + }, + { + "date": "2025-10-06", + "value": 42.5 + }, + { + "date": "2025-10-12", + "value": 27.1 + }, + { + "date": "2025-10-18", + "value": 30.7 + }, + { + "date": "2025-11-04", + "value": 31.9 + }, + { + "date": "2025-11-10", + "value": 36.6 + }, + { + "date": "2025-11-16", + "value": 38.9 + }, + { + "date": "2025-12-05", + "value": 31.9 + }, + { + "date": "2025-12-11", + "value": 34.2 + }, + { + "date": "2025-12-17", + "value": 37.8 + }, + { + "date": "2026-01-06", + "value": 30.7 + }, + { + "date": "2026-01-12", + "value": 34.2 + }, + { + "date": "2026-01-18", + "value": 36.6 + }, + { + "date": "2026-02-04", + "value": 38.9 + }, + { + "date": "2026-02-10", + "value": 42.5 + }, + { + "date": "2026-02-16", + "value": 46.0 + }, + { + "date": "2026-03-05", + "value": 38.9 + }, + { + "date": "2026-03-11", + "value": 42.5 + }, + { + "date": "2026-03-17", + "value": 27.1 + }, + { + "date": "2026-04-06", + "value": 47.2 + }, + { + "date": "2026-04-12", + "value": 31.9 + }, + { + "date": "2026-04-18", + "value": 36.6 + }, + { + "date": "2026-05-04", + "value": 28.3 + }, + { + "date": "2026-05-10", + "value": 31.9 + }, + { + "date": "2026-05-16", + "value": 34.2 + } + ], + "monthly": [ + { + "month": "2022-07", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2022-11", + "mean": 41.3, + "median": 41.3, + "p10": 41.3, + "p25": 41.3, + "p75": 41.3, + "p90": 41.3, + "n": 1 + }, + { + "month": "2023-03", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2023-07", + "mean": 49.6, + "median": 49.6, + "p10": 49.6, + "p25": 49.6, + "p75": 49.6, + "p90": 49.6, + "n": 1 + }, + { + "month": "2023-10", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2024-02", + "mean": 64.9, + "median": 64.9, + "p10": 64.9, + "p25": 64.9, + "p75": 64.9, + "p90": 64.9, + "n": 1 + }, + { + "month": "2024-05", + "mean": 29.5, + "median": 29.5, + "p10": 29.5, + "p25": 29.5, + "p75": 29.5, + "p90": 29.5, + "n": 1 + }, + { + "month": "2024-08", + "mean": 44.8, + "median": 44.8, + "p10": 44.8, + "p25": 44.8, + "p75": 44.8, + "p90": 44.8, + "n": 1 + }, + { + "month": "2024-11", + "mean": 17.7, + "median": 17.7, + "p10": 17.7, + "p25": 17.7, + "p75": 17.7, + "p90": 17.7, + "n": 1 + }, + { + "month": "2025-01", + "mean": 37.8, + "median": 37.8, + "p10": 37.8, + "p25": 37.8, + "p75": 37.8, + "p90": 37.8, + "n": 1 + }, + { + "month": "2025-04", + "mean": 33.0, + "median": 33.0, + "p10": 33.0, + "p25": 33.0, + "p75": 33.0, + "p90": 33.0, + "n": 1 + }, + { + "month": "2025-06", + "mean": 53.1, + "median": 53.1, + "p10": 53.1, + "p25": 53.1, + "p75": 53.1, + "p90": 53.1, + "n": 1 + }, + { + "month": "2025-07", + "mean": 35.4, + "median": 35.4, + "p10": 35.4, + "p25": 35.4, + "p75": 35.4, + "p90": 35.4, + "n": 1 + }, + { + "month": "2025-08", + "mean": 26.0, + "median": 26.0, + "p10": 26.0, + "p25": 26.0, + "p75": 26.0, + "p90": 26.0, + "n": 1 + }, + { + "month": "2025-09", + "mean": 41.1, + "median": 43.7, + "p10": 34.2, + "p25": 39.5, + "p75": 45.2, + "p90": 45.7, + "n": 4 + }, + { + "month": "2025-10", + "mean": 33.4, + "median": 30.7, + "p10": 27.8, + "p25": 28.9, + "p75": 36.6, + "p90": 40.1, + "n": 3 + }, + { + "month": "2025-11", + "mean": 35.8, + "median": 36.6, + "p10": 32.8, + "p25": 34.2, + "p75": 37.8, + "p90": 38.5, + "n": 3 + }, + { + "month": "2025-12", + "mean": 34.6, + "median": 34.2, + "p10": 32.3, + "p25": 33.0, + "p75": 36.0, + "p90": 37.1, + "n": 3 + }, + { + "month": "2026-01", + "mean": 33.9, + "median": 34.2, + "p10": 31.4, + "p25": 32.4, + "p75": 35.4, + "p90": 36.1, + "n": 3 + }, + { + "month": "2026-02", + "mean": 42.5, + "median": 42.5, + "p10": 39.6, + "p25": 40.7, + "p75": 44.2, + "p90": 45.3, + "n": 3 + }, + { + "month": "2026-03", + "mean": 36.2, + "median": 38.9, + "p10": 29.5, + "p25": 33.0, + "p75": 40.7, + "p90": 41.8, + "n": 3 + }, + { + "month": "2026-04", + "mean": 38.6, + "median": 36.6, + "p10": 32.8, + "p25": 34.2, + "p75": 41.9, + "p90": 45.1, + "n": 3 + }, + { + "month": "2026-05", + "mean": 31.5, + "median": 31.9, + "p10": 29.0, + "p25": 30.1, + "p75": 33.0, + "p90": 33.7, + "n": 3 + } + ], + "stats": { + "n": 42, + "mean": 36.9, + "median": 35.4, + "std": 7.1, + "min": 17.7, + "max": 64.9, + "p25": 31.9, + "p75": 42.5, + "p85": 44.8, + "p95": 47.2 + }, + "plifz": 28, + "plifz_note": null, + "pct_exceeding_plifz": 61.9, + "annotations": [], + "cost": null, + "detail_rows": null, + "ref_date_col": null, + "n_batches": null, + "n_movements": 15, + "yield_data": null, + "consumption_data": null, + "schema_version": "1.0" +} diff --git a/apps/hash-api/src/seed-data/supply-chain-demo/current.json b/apps/hash-api/src/seed-data/supply-chain-demo/current.json new file mode 100644 index 00000000000..50a3d9d0c0d --- /dev/null +++ b/apps/hash-api/src/seed-data/supply-chain-demo/current.json @@ -0,0 +1,3 @@ +{ + "datasetVersion": "2026-06-17.1" +} diff --git a/apps/hash-api/src/storage/local-file-storage.ts b/apps/hash-api/src/storage/local-file-storage.ts index bd21447cdf1..46a613ee3d7 100644 --- a/apps/hash-api/src/storage/local-file-storage.ts +++ b/apps/hash-api/src/storage/local-file-storage.ts @@ -13,6 +13,7 @@ import type { FileStorageProvider, GetFileEntityStorageKeyParams, GetFlowOutputStorageKeyParams, + PresignedDownloadByKeyRequest, PresignedDownloadRequest, PresignedPutUpload, PresignedStorageRequest, @@ -92,6 +93,13 @@ export class LocalFileSystemStorageProvider implements FileStorageProvider { .href as Url; } + async presignDownloadByKey( + params: PresignedDownloadByKeyRequest, + ): Promise { + return new URL(path.join(DOWNLOAD_BASE_URL, params.key), this.apiOrigin) + .href as Url; + } + getFileEntityStorageKey({ entityId, editionIdentifier, diff --git a/apps/hash-frontend/package.json b/apps/hash-frontend/package.json index 4766e03e01a..e4c170964cb 100644 --- a/apps/hash-frontend/package.json +++ b/apps/hash-frontend/package.json @@ -21,6 +21,7 @@ "dependencies": { "@ai-sdk/openai": "3.0.63", "@apollo/client": "3.10.5", + "@ark-ui/react": "5.26.2", "@blockprotocol/core": "0.1.5", "@blockprotocol/graph": "workspace:*", "@blockprotocol/hook": "0.1.8", @@ -65,12 +66,14 @@ "@sigma/node-border": "3.0.0", "@sigma/node-image": "3.0.0", "@svgr/webpack": "8.1.0", + "@tanstack/react-table": "8.21.3", "@tldraw/editor": "patch:@tldraw/editor@npm%3A2.0.0-alpha.12#~/.yarn/patches/@tldraw-editor-npm-2.0.0-alpha.12-ba59bf001c.patch", "@tldraw/primitives": "2.0.0-alpha.12", "@tldraw/tldraw": "2.0.0-alpha.12", "@tldraw/tlvalidate": "2.0.0-alpha.12", "@types/prismjs": "1.26.5", "@vercel/edge-config": "0.4.1", + "@xyflow/react": "12.10.1", "ai": "6.0.182", "axios": "1.16.1", "buffer": "6.0.3", @@ -124,6 +127,7 @@ "react-virtuoso": "4.14.1", "react-window": "1.8.11", "reactflow": "11.11.4", + "recharts": "3.8.0", "remark-gfm": "4.0.1", "safe-stable-stringify": "2.5.0", "setimmediate": "1.0.5", diff --git a/apps/hash-frontend/panda.config.ts b/apps/hash-frontend/panda.config.ts index b40b48fc832..fd54756261b 100644 --- a/apps/hash-frontend/panda.config.ts +++ b/apps/hash-frontend/panda.config.ts @@ -22,10 +22,15 @@ export default defineConfig({ ...scopedThemeConfig(".hash-ds-root"), /** - * Only styles used inside ds-components itself — this app does not author - * Panda styles. Add `./src` globs here if `css()` calls are introduced. + * Styles used inside ds-components itself, plus the ported value-chain-timing + * supply-chain tool (`src/vct`) and its route pages, which author Panda + * `css()` calls against the ds-components preset tokens. */ - include: [require.resolve("@hashintel/ds-components/panda.buildinfo.json")], + include: [ + require.resolve("@hashintel/ds-components/panda.buildinfo.json"), + "./src/vct/**/*.{ts,tsx}", + "./src/pages/supply-chain/**/*.{ts,tsx}", + ], exclude: [], diff --git a/apps/hash-frontend/src/lib/supply-chain/data.ts b/apps/hash-frontend/src/lib/supply-chain/data.ts new file mode 100644 index 00000000000..875e88847c4 --- /dev/null +++ b/apps/hash-frontend/src/lib/supply-chain/data.ts @@ -0,0 +1,119 @@ +import { + fetchArtifactJson, + fetchQueryArtifact, + fetchQueryArtifacts, +} from "./query-client"; + +import type { WebId } from "@blockprotocol/type-system"; + +/** + * Data-access layer for the supply-chain (value-chain-timing) views, ported + * from the standalone SPA's `shared/data.ts`. Where the SPA fetched static JSON + * from `/data/...`, these go through the auth-gated query gateway, scoped to a + * `webId`. View-layer payload types (graph, step detail, site summary) are + * supplied by the caller as type parameters during the component migration. + */ + +/** A product as listed in `products.json`. */ +export interface SupplyChainProduct { + id: string; + name: string; + material: string; +} + +/** A selectable site (plant) as listed in `sites.json`. */ +export interface SiteRef { + slug: string; + name: string; +} + +export const fetchProducts = (webId: WebId): Promise => + fetchQueryArtifact({ + query: "listProducts", + webIds: [webId], + }); + +export const fetchSites = (webId: WebId): Promise => + fetchQueryArtifact({ + query: "listSites", + webIds: [webId], + }).catch(() => []); + +export const fetchGraph = ( + webId: WebId, + productId: string, +): Promise => + fetchQueryArtifact({ + query: "productGraph", + args: { productId }, + webIds: [webId], + }); + +export const fetchStepDetail = ( + webId: WebId, + productId: string, + stepId: string, +): Promise => + fetchQueryArtifact({ + query: "stepDetail", + args: { productId, stepId }, + webIds: [webId], + }); + +export const fetchSiteSummary = async ( + webId: WebId, + siteId: string, +): Promise => { + try { + return await fetchQueryArtifact({ + query: "siteSummary", + args: { siteId }, + webIds: [webId], + }); + } catch { + return null; + } +}; + +/** + * Site-wide supplier performance. The query resolves two artifacts – + * `performance` (aggregates) and `lines` (raw schedule lines for client-side + * time-window recompute). We re-attach `lines` onto the performance payload to + * match the SPA's `SiteSupplierPerformance` shape. Missing lines are tolerated. + */ +export const fetchSupplierPerformance = async < + Performance extends { lines?: unknown[] } = { lines?: unknown[] }, + Line = unknown, +>( + webId: WebId, +): Promise => { + try { + const artifacts = await fetchQueryArtifacts({ + query: "supplierPerformance", + webIds: [webId], + }); + + const perfRef = artifacts.performance; + if (!perfRef) { + return null; + } + const performance = await fetchArtifactJson(perfRef); + + if (!performance.lines && artifacts.lines) { + try { + const companion = await fetchArtifactJson<{ lines?: Line[] }>( + artifacts.lines, + ); + if (companion.lines) { + performance.lines = companion.lines; + } + } catch { + // Companion lines file absent: leave aggregates-only. + } + } + + return performance; + } catch { + return null; + } +}; diff --git a/apps/hash-frontend/src/lib/supply-chain/query-client.ts b/apps/hash-frontend/src/lib/supply-chain/query-client.ts new file mode 100644 index 00000000000..ee7511d948f --- /dev/null +++ b/apps/hash-frontend/src/lib/supply-chain/query-client.ts @@ -0,0 +1,104 @@ +import { apiOrigin } from "@local/hash-isomorphic-utils/environment"; + +import type { + ArtifactRef, + QueryInvocation, + QueryResponse, + QueryResult, +} from "@local/hash-isomorphic-utils/query/types"; + +/** + * Client for the generic query gateway (`POST /api/query`). The gateway returns + * short-lived URLs; artifact bytes are fetched directly from storage (the data + * plane) rather than proxied through the API. + */ + +export class QueryError extends Error { + constructor(message: string) { + super(message); + this.name = "QueryError"; + } +} + +/** POST a batch of named-query invocations and return their results. */ +export const runQueries = async ( + requests: QueryInvocation[], +): Promise => { + const response = await fetch(`${apiOrigin}/api/query`, { + method: "POST", + credentials: "include", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ requests }), + }); + + if (!response.ok) { + throw new QueryError(`Query request failed with status ${response.status}`); + } + + const body = (await response.json()) as QueryResponse; + return body.results; +}; + +/** Fetch and JSON-parse the bytes referenced by a resolved artifact. */ +export const fetchArtifactJson = async (ref: ArtifactRef): Promise => { + // Presigned (S3) URLs carry auth in the query string and must NOT receive + // cookies; same-origin (local dev) URLs go through the API and need them. + const sameOrigin = ref.url.startsWith(apiOrigin); + const response = await fetch(ref.url, { + credentials: sameOrigin ? "include" : "omit", + }); + + if (!response.ok) { + throw new QueryError( + `Artifact "${ref.name}" fetch failed with status ${response.status}`, + ); + } + + return (await response.json()) as T; +}; + +const resultReady = (result: QueryResult | undefined): QueryResult => { + if (!result) { + throw new QueryError("Empty query response"); + } + if (result.status === "error") { + throw new QueryError(result.error ?? "Query returned an error"); + } + if (result.status !== "ready" || !result.artifacts?.length) { + throw new QueryError(`Query result not ready (status: ${result.status})`); + } + return result; +}; + +/** + * Run a single named query and return the parsed JSON of one of its artifacts + * (the primary/first by default, or the named one via `opts.artifact`). + */ +export const fetchQueryArtifact = async ( + invocation: Omit, + opts?: { artifact?: string }, +): Promise => { + const [result] = await runQueries([{ id: "q0", ...invocation }]); + const ready = resultReady(result); + + const ref = opts?.artifact + ? ready.artifacts!.find((a) => a.name === opts.artifact) + : ready.artifacts![0]; + + if (!ref) { + throw new QueryError( + `Artifact "${opts?.artifact ?? "(primary)"}" not present in result`, + ); + } + + return fetchArtifactJson(ref); +}; + +/** Like {@link fetchQueryArtifact} but resolves multiple named artifacts at once. */ +export const fetchQueryArtifacts = async ( + invocation: Omit, +): Promise> => { + const [result] = await runQueries([{ id: "q0", ...invocation }]); + const ready = resultReady(result); + return Object.fromEntries(ready.artifacts!.map((ref) => [ref.name, ref])); +}; diff --git a/apps/hash-frontend/src/pages/_app.page.tsx b/apps/hash-frontend/src/pages/_app.page.tsx index d272b4dc89d..86623505ad2 100644 --- a/apps/hash-frontend/src/pages/_app.page.tsx +++ b/apps/hash-frontend/src/pages/_app.page.tsx @@ -312,6 +312,13 @@ const featureFlagHiddenPathnames: Record = { notes: ["/notes"], workers: ["/goals", "/flows", "/workers", "/agents"], ai: ["/goals"], + supplyChain: [ + "/supply-chain", + "/supply-chain/methodology", + "/supply-chain/product/[productId]", + "/supply-chain/site/[siteId]", + "/supply-chain/site/[siteId]/opportunity/[opportunityType]/[productId]/[stepId]", + ], }; AppWithTypeSystemContextProvider.getInitialProps = async (appContext) => { diff --git a/apps/hash-frontend/src/pages/supply-chain/index.page.tsx b/apps/hash-frontend/src/pages/supply-chain/index.page.tsx new file mode 100644 index 00000000000..2a6b31ff6a1 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/index.page.tsx @@ -0,0 +1,27 @@ +import { useRouter } from "next/router"; +import { useEffect } from "react"; + +import { useRegistry } from "../../vct/supply-chain/shared/registry-context"; +import { getSupplyChainLayout } from "./shared/supply-chain-layout"; + +import type { NextPageWithLayout } from "../../shared/layout"; + +/** Supply-chain landing: send to the first product. */ +const SupplyChainIndexPage: NextPageWithLayout = () => { + const router = useRouter(); + const { products } = useRegistry(); + + useEffect(() => { + const firstProduct = products[0]; + if (!firstProduct) { + return; + } + void router.replace(`/supply-chain/product/${firstProduct.id}`); + }, [products, router]); + + return null; +}; + +SupplyChainIndexPage.getLayout = getSupplyChainLayout; + +export default SupplyChainIndexPage; diff --git a/apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx new file mode 100644 index 00000000000..08b9d591fd3 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx @@ -0,0 +1,91 @@ +import { useRouter } from "next/router"; +import { useCallback, useEffect, useState } from "react"; + +import { css } from "@hashintel/ds-helpers/css"; + +import { Overview } from "../../../vct/supply-chain/product"; +import { fetchGraph } from "../../../vct/supply-chain/shared/data"; +import { + ErrorState, + LoadingState, +} from "../../../vct/supply-chain/shared/load-state"; +import { useSearchParams } from "../../../vct/supply-chain/shared/use-search-params"; +import { getSupplyChainLayout } from "../shared/supply-chain-layout"; + +import type { NextPageWithLayout } from "../../../shared/layout"; +import type { GraphData } from "../../../vct/supply-chain/shared/types"; + +const loadingH = css({ h: "64" }); +const errorPad = css({ px: "6", py: "4" }); + +const ProductPage: NextPageWithLayout = () => { + const router = useRouter(); + const productId = + typeof router.query["product-id"] === "string" + ? router.query["product-id"] + : ""; + + const [searchParams, setSearchParams] = useSearchParams(); + const [graph, setGraph] = useState(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + // Selected step lives in the URL (`?step`) so deep links and reloads survive. + const selectedStepId = searchParams.get("step") ?? null; + const setSelectedStepId = useCallback( + (stepId: string | null) => { + setSearchParams( + (prev) => { + const next = new URLSearchParams(prev); + if (stepId) { + next.set("step", stepId); + } else { + next.delete("step"); + } + return next; + }, + { replace: true }, + ); + }, + [setSearchParams], + ); + + useEffect(() => { + if (!productId) { + return; + } + setLoading(true); + setError(null); + fetchGraph(productId) + .then(setGraph) + .catch((caught) => + setError(caught instanceof Error ? caught.message : String(caught)), + ) + .finally(() => setLoading(false)); + }, [productId]); + + if (loading) { + return ( + + ); + } + if (error) { + return ; + } + if (!graph) { + return null; + } + + return ( + + ); +}; + +ProductPage.getLayout = getSupplyChainLayout; + +export default ProductPage; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx new file mode 100644 index 00000000000..81a3cc755f2 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx @@ -0,0 +1,62 @@ +import { useRef } from "react"; + +import { PortalContainerContext } from "@hashintel/ds-components"; + +import { getLayoutWithSidebar } from "../../../shared/layout"; +import { HEADER_HEIGHT } from "../../../shared/layout/layout-with-header/page-header"; +import { AppShell } from "../../../vct/supply-chain/app-shell"; +import { useActiveWorkspace } from "../../shared/workspace-context"; + +import type { ReactElement, ReactNode } from "react"; + +/** + * Layout shared by every `/supply-chain/*` page. Mounts the ported + * value-chain-timing `AppShell` inside hash's sidebar chrome, scoped to the + * active web — the gateway transport queries `/api/query` for that `webId`. + * + * The subtree is wrapped in `.hash-ds-root` so the ds-components Panda tokens + * resolve, and that element is supplied as the `PortalContainerContext` so ds + * and Ark overlays (dialogs, tooltips, selects) portal *inside* the token + * scope rather than at `document.body` (mirrors the standalone tool's `_app`). + * + * `AppShell` is keyed by the active web so switching workspace remounts it and + * reloads the product/site registry for the new scope. + */ +const SupplyChainShell = ({ children }: { children: ReactNode }) => { + const rootRef = useRef(null); + const { activeWorkspaceWebId } = useActiveWorkspace(); + + return ( + + {/* + Bound the ds scope to the viewport height below hash's global header so + the ported AppShell (which fills this box with `height:100%`) can scroll + its content pane internally instead of overflowing the page. This is the + host-side counterpart to the standalone tool's `100dvh` `.vct-root`. + */} +
+ {activeWorkspaceWebId ? ( + + {children} + + ) : null} +
+
+ ); +}; + +export const getSupplyChainLayout = (page: ReactElement): ReactNode => + getLayoutWithSidebar({page}, { + fullWidth: true, + }); diff --git a/apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx new file mode 100644 index 00000000000..a53a8d1e730 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx @@ -0,0 +1,22 @@ +import { useRouter } from "next/router"; + +import { useRegistry } from "../../../vct/supply-chain/shared/registry-context"; +import { SiteOverview } from "../../../vct/supply-chain/site"; +import { getSupplyChainLayout } from "../shared/supply-chain-layout"; + +import type { NextPageWithLayout } from "../../../shared/layout"; + +const SitePage: NextPageWithLayout = () => { + const router = useRouter(); + const { products, sites } = useRegistry(); + const siteId = + typeof router.query["site-id"] === "string" + ? router.query["site-id"] + : (sites[0]?.slug ?? ""); + + return ; +}; + +SitePage.getLayout = getSupplyChainLayout; + +export default SitePage; diff --git a/apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx new file mode 100644 index 00000000000..ae973d04f23 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx @@ -0,0 +1,36 @@ +import { useRouter } from "next/router"; + +import { OpportunityBrief } from "../../../../../../../vct/supply-chain/opportunity"; +import { useRegistry } from "../../../../../../../vct/supply-chain/shared/registry-context"; +import { getSupplyChainLayout } from "../../../../../shared/supply-chain-layout"; + +import type { NextPageWithLayout } from "../../../../../../../shared/layout"; +import type { OpportunityType } from "../../../../../../../vct/supply-chain/opportunity/opportunity-utils"; + +const normaliseOpportunityType = (value: string | undefined): OpportunityType => + value === "planning" ? "planning" : "dwell"; + +const OpportunityPage: NextPageWithLayout = () => { + const router = useRouter(); + const { products, sites } = useRegistry(); + const query = router.query as { + "site-id"?: string; + "opportunity-type"?: string; + "product-id"?: string; + "step-id"?: string; + }; + + return ( + + ); +}; + +OpportunityPage.getLayout = getSupplyChainLayout; + +export default OpportunityPage; diff --git a/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx b/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx index 563f177cb5d..33d1204e44b 100644 --- a/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx +++ b/apps/hash-frontend/src/shared/layout/layout-with-sidebar/sidebar.tsx @@ -1,4 +1,4 @@ -import { faHome } from "@fortawesome/free-solid-svg-icons"; +import { faHome, faTruckFast } from "@fortawesome/free-solid-svg-icons"; import { Box, Collapse, Drawer } from "@mui/material"; import { useRouter } from "next/router"; import { @@ -195,6 +195,17 @@ export const PageSidebar: FunctionComponent = () => { }, ] : []), + ...(enabledFeatureFlags.supplyChain + ? [ + { + title: "Supply Chain", + path: "/supply-chain", + icon: , + activeIfPathMatches: /^\/supply-chain(\/|$)/, + tooltipTitle: "", + }, + ] + : []), ]; }, [ preferences.sidebarSections.entities.variant, @@ -204,6 +215,7 @@ export const PageSidebar: FunctionComponent = () => { numberOfUnreadNotifications, pendingInvites.length, enabledFeatureFlags.notes, + enabledFeatureFlags.supplyChain, ]); return ( diff --git a/infra/compose/compose.yml b/infra/compose/compose.yml index c3f70c83157..da1d660f1f2 100644 --- a/infra/compose/compose.yml +++ b/infra/compose/compose.yml @@ -395,7 +395,7 @@ services: AWS_S3_UPLOADS_BUCKET: ${AWS_S3_UPLOADS_BUCKET:-dev-hash-bucket} entrypoint: | /bin/sh -c ' - mc config host add myminio http://minio:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD && + mc alias set myminio http://minio:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD && echo "Creating bucket $$AWS_S3_UPLOADS_BUCKET" && mc mb myminio/$$AWS_S3_UPLOADS_BUCKET --ignore-existing ' diff --git a/libs/@local/hash-backend-utils/src/file-storage.ts b/libs/@local/hash-backend-utils/src/file-storage.ts index 4864cadb1d6..edff5b26a46 100644 --- a/libs/@local/hash-backend-utils/src/file-storage.ts +++ b/libs/@local/hash-backend-utils/src/file-storage.ts @@ -55,6 +55,18 @@ export interface FileStorageProvider { */ presignDownload(params: PresignedDownloadRequest): Promise; + /** + * Presigns a download URL for an object identified solely by its storage key, + * using the provider's own (default) storage configuration. + * + * Unlike {@link presignDownload}, this does not require a file entity – it is + * used for server-managed objects (e.g. precomputed analysis artifacts served + * by the query gateway) that are not represented as entities in the graph. + * + * @return The time-limited download URL to access the object. + */ + presignDownloadByKey(params: PresignedDownloadByKeyRequest): Promise; + /** * Presigns a file upload request for a client to later upload a file * @return Promise contains the presignedPut object with the url to PUT the file to, and the file storage @@ -141,6 +153,14 @@ export interface PresignedDownloadRequest { expiresInSeconds: number; } +/** Parameters needed to presign the download of a server-managed object by key */ +export interface PresignedDownloadByKeyRequest { + /** Storage key of the object, relative to the provider's default location */ + key: string; + /** Expiry delay (in seconds) for the download authorisation */ + expiresInSeconds: number; +} + /** * Data returned for a client to be able to send a PUT request to upload a file * PUT rather than POST is used for R2 compatibility diff --git a/libs/@local/hash-backend-utils/src/file-storage/aws-s3-storage-provider.ts b/libs/@local/hash-backend-utils/src/file-storage/aws-s3-storage-provider.ts index 258cfd8b5d3..5e6daf23888 100644 --- a/libs/@local/hash-backend-utils/src/file-storage/aws-s3-storage-provider.ts +++ b/libs/@local/hash-backend-utils/src/file-storage/aws-s3-storage-provider.ts @@ -14,6 +14,7 @@ import type { FileStorageProvider, GetFileEntityStorageKeyParams, GetFlowOutputStorageKeyParams, + PresignedDownloadByKeyRequest, PresignedDownloadRequest, PresignedStorageRequest, StorageType, @@ -197,6 +198,27 @@ export class AwsS3StorageProvider implements FileStorageProvider { })) as Url; } + async presignDownloadByKey({ + key, + expiresInSeconds, + }: PresignedDownloadByKeyRequest): Promise { + const filename = key.split("/").pop() ?? key; + const mimeType = mime.lookup(filename) || "application/octet-stream"; + const safeContentType = getSafeContentType(mimeType); + + const command = new GetObjectCommand({ + Bucket: this.bucket, + Key: key, + ...(safeContentType && { + ResponseContentType: safeContentType, + }), + }); + + return (await getSignedUrl(this.client, command, { + expiresIn: expiresInSeconds, + })) as Url; + } + getFileEntityStorageKey({ entityId, editionIdentifier, diff --git a/libs/@local/hash-isomorphic-utils/src/feature-flags.ts b/libs/@local/hash-isomorphic-utils/src/feature-flags.ts index ec49d77b32a..4280722c832 100644 --- a/libs/@local/hash-isomorphic-utils/src/feature-flags.ts +++ b/libs/@local/hash-isomorphic-utils/src/feature-flags.ts @@ -23,6 +23,10 @@ export const featureFlags = [ * Whether AI-related features are enabled, e.g. embedding creation, AI-utilising flow steps */ "ai", + /** + * Whether the supply chain dashboard views are accessible + */ + "supplyChain", ] as const; export type FeatureFlag = (typeof featureFlags)[number]; diff --git a/libs/@local/hash-isomorphic-utils/src/query/types.ts b/libs/@local/hash-isomorphic-utils/src/query/types.ts new file mode 100644 index 00000000000..52f1d51008c --- /dev/null +++ b/libs/@local/hash-isomorphic-utils/src/query/types.ts @@ -0,0 +1,64 @@ +import type { WebId } from "@blockprotocol/type-system"; + +/** + * Wire types for the generic query gateway (`POST /api/query`). + * + * The gateway resolves *named queries* (registered server-side) to one or more + * stored artifacts and returns short-lived URLs the client fetches directly + * from storage. The same contract supports a future live-compute path: a result + * may come back as `computing` rather than `ready` without any client change. + */ + +/** A single named-query invocation within a batch request. */ +export interface QueryInvocation { + /** Caller-chosen id used to correlate this invocation with its result. */ + id: string; + /** Registered query name, e.g. `"productGraph"`. */ + query: string; + /** Query-specific arguments; validated server-side against the query. */ + args?: Record; + /** + * Web(s) the query is scoped to. The authenticated actor must hold a role in + * every listed web, otherwise the whole invocation is rejected. + */ + webIds: WebId[]; +} + +/** Request body for `POST /api/query`. */ +export interface QueryRequest { + requests: QueryInvocation[]; +} + +/** A resolved artifact the client can fetch directly from storage. */ +export interface ArtifactRef { + /** Logical name of the artifact within the result, e.g. `"graph"`. */ + name: string; + /** Wire format/encoding hint, e.g. `"json"` (served with `Content-Encoding`). */ + format: string; + /** Time-limited URL to fetch the artifact bytes directly from storage. */ + url: string; + /** Content hash for aggressive client-side caching (optional). */ + contentHash?: string; + /** ISO timestamp after which `url` may no longer be valid (optional). */ + expiresAt?: string; +} + +export type QueryResultStatus = "ready" | "computing" | "error"; + +/** The result of a single {@link QueryInvocation}. */ +export interface QueryResult { + /** Echoes the invocation `id`. */ + id: string; + status: QueryResultStatus; + /** Present when `status === "ready"`. */ + artifacts?: ArtifactRef[]; + /** Present when `status === "computing"`: hint for the client poll interval. */ + retryAfterMs?: number; + /** Present when `status === "error"`: human-readable reason. */ + error?: string; +} + +/** Response body for `POST /api/query`. */ +export interface QueryResponse { + results: QueryResult[]; +} diff --git a/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json b/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json index 90cc49f7d1f..8dfb7ca1f5b 100644 --- a/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json +++ b/libs/@local/tsconfig/legacy-base-tsconfig-to-refactor.json @@ -30,6 +30,9 @@ "@hashintel/petrinaut-core/examples": [ "../../@hashintel/petrinaut-core/src/examples/index.ts" ], + "@hashintel/ds-helpers/*": [ + "../../@hashintel/ds-helpers/styled-system/*/index.d.ts" + ], "@local/advanced-types/*": ["../advanced-types/src/*.ts"], "@local/hash-backend-utils/*": ["../hash-backend-utils/src/*.ts"], "@local/hash-graph-client/*": ["../graph/client/typescript/*.ts"], diff --git a/tests/hash-backend-integration/src/tests/graph/knowledge/system-types/file.test.ts b/tests/hash-backend-integration/src/tests/graph/knowledge/system-types/file.test.ts index 0301fb95e22..08f86eb7bed 100644 --- a/tests/hash-backend-integration/src/tests/graph/knowledge/system-types/file.test.ts +++ b/tests/hash-backend-integration/src/tests/graph/knowledge/system-types/file.test.ts @@ -65,6 +65,7 @@ describe("File", () => { Promise.resolve(Buffer.from("mock-download-body")), ), presignDownload: vi.fn(() => Promise.resolve(downloadUrl)), + presignDownloadByKey: vi.fn(() => Promise.resolve(downloadUrl)), presignUpload: vi.fn(() => Promise.resolve({ fileStorageProperties: { diff --git a/tests/hash-backend-integration/src/tests/util.ts b/tests/hash-backend-integration/src/tests/util.ts index 02d069c3cf8..1fe8b052591 100644 --- a/tests/hash-backend-integration/src/tests/util.ts +++ b/tests/hash-backend-integration/src/tests/util.ts @@ -81,6 +81,11 @@ export const createTestImpureGraphContext = (): ImpureGraphContext< "File presign download not implemented in tests. Override with mock to test.", ); }, + presignDownloadByKey: (_params) => { + throw new Error( + "File presign download by key not implemented in tests. Override with mock to test.", + ); + }, presignUpload: (_params) => { throw new Error( "File presign upload not implemented in tests. Override with mock to test.", diff --git a/yarn.lock b/yarn.lock index aadf30c5c79..fb5650319de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -573,6 +573,7 @@ __metadata: dependencies: "@ai-sdk/openai": "npm:3.0.63" "@apollo/client": "npm:3.10.5" + "@ark-ui/react": "npm:5.26.2" "@blockprotocol/core": "npm:0.1.5" "@blockprotocol/graph": "workspace:*" "@blockprotocol/hook": "npm:0.1.8" @@ -625,6 +626,7 @@ __metadata: "@sigma/node-border": "npm:3.0.0" "@sigma/node-image": "npm:3.0.0" "@svgr/webpack": "npm:8.1.0" + "@tanstack/react-table": "npm:8.21.3" "@tldraw/editor": "patch:@tldraw/editor@npm%3A2.0.0-alpha.12#~/.yarn/patches/@tldraw-editor-npm-2.0.0-alpha.12-ba59bf001c.patch" "@tldraw/primitives": "npm:2.0.0-alpha.12" "@tldraw/tldraw": "npm:2.0.0-alpha.12" @@ -645,6 +647,7 @@ __metadata: "@types/url-regex-safe": "npm:1.0.2" "@vercel/edge-config": "npm:0.4.1" "@welldone-software/why-did-you-render": "npm:10.0.1" + "@xyflow/react": "npm:12.10.1" ai: "npm:6.0.182" axios: "npm:1.16.1" buffer: "npm:6.0.3" @@ -701,6 +704,7 @@ __metadata: react-virtuoso: "npm:4.14.1" react-window: "npm:1.8.11" reactflow: "npm:11.11.4" + recharts: "npm:3.8.0" remark-gfm: "npm:4.0.1" rimraf: "npm:6.1.3" safe-stable-stringify: "npm:2.5.0" @@ -12141,6 +12145,28 @@ __metadata: languageName: node linkType: hard +"@reduxjs/toolkit@npm:^1.9.0 || 2.x.x": + version: 2.12.0 + resolution: "@reduxjs/toolkit@npm:2.12.0" + dependencies: + "@standard-schema/spec": "npm:^1.0.0" + "@standard-schema/utils": "npm:^0.3.0" + immer: "npm:^11.0.0" + redux: "npm:^5.0.1" + redux-thunk: "npm:^3.1.0" + reselect: "npm:^5.1.0" + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 || ^19 + react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + checksum: 10c0/2b85e31294a7139994fd78b08eb3ce706ce3b03b5081c13403b93ba4883a152d637171e4d9d969766238851f8915b1daa9f36b5a0a458aff0ff7600ee38795c9 + languageName: node + linkType: hard + "@regru/eslint-plugin-prefer-early-return@npm:^1.0.0": version: 1.0.0 resolution: "@regru/eslint-plugin-prefer-early-return@npm:1.0.0" @@ -14767,6 +14793,13 @@ __metadata: languageName: node linkType: hard +"@standard-schema/utils@npm:^0.3.0": + version: 0.3.0 + resolution: "@standard-schema/utils@npm:0.3.0" + checksum: 10c0/6eb74cd13e52d5fc74054df51e37d947ef53f3ab9e02c085665dcca3c38c60ece8d735cebbdf18fbb13c775fbcb9becb3f53109b0e092a63f0f7389ce0993fd0 + languageName: node + linkType: hard + "@storybook/builder-vite@npm:10.2.19": version: 10.2.19 resolution: "@storybook/builder-vite@npm:10.2.19" @@ -15267,6 +15300,18 @@ __metadata: languageName: node linkType: hard +"@tanstack/react-table@npm:8.21.3": + version: 8.21.3 + resolution: "@tanstack/react-table@npm:8.21.3" + dependencies: + "@tanstack/table-core": "npm:8.21.3" + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: 10c0/85d1d0fcb690ecc011f68a5a61c96f82142e31a0270dcf9cbc699a6f36715b1653fe6ff1518302a6d08b7093351fc4cabefd055a7db3cd8ac01e068956b0f944 + languageName: node + linkType: hard + "@tanstack/react-virtual@npm:3.13.24": version: 3.13.24 resolution: "@tanstack/react-virtual@npm:3.13.24" @@ -15286,6 +15331,13 @@ __metadata: languageName: node linkType: hard +"@tanstack/table-core@npm:8.21.3": + version: 8.21.3 + resolution: "@tanstack/table-core@npm:8.21.3" + checksum: 10c0/40e3560e6d55e07cc047024aa7f83bd47a9323d21920d4adabba8071fd2d21230c48460b26cedf392588f8265b9edc133abb1b0d6d0adf4dae0970032900a8c9 + languageName: node + linkType: hard + "@tanstack/virtual-core@npm:3.14.0": version: 3.14.0 resolution: "@tanstack/virtual-core@npm:3.14.0" @@ -15966,7 +16018,7 @@ __metadata: languageName: node linkType: hard -"@types/d3-array@npm:*": +"@types/d3-array@npm:*, @types/d3-array@npm:^3.0.3": version: 3.2.2 resolution: "@types/d3-array@npm:3.2.2" checksum: 10c0/6137cb97302f8a4f18ca22c0560c585cfcb823f276b23d89f2c0c005d72697ec13bca671c08e68b4b0cabd622e3f0e91782ee221580d6774074050be96dd7028 @@ -16045,7 +16097,7 @@ __metadata: languageName: node linkType: hard -"@types/d3-ease@npm:*": +"@types/d3-ease@npm:*, @types/d3-ease@npm:^3.0.0": version: 3.0.2 resolution: "@types/d3-ease@npm:3.0.2" checksum: 10c0/aff5a1e572a937ee9bff6465225d7ba27d5e0c976bd9eacdac2e6f10700a7cb0c9ea2597aff6b43a6ed850a3210030870238894a77ec73e309b4a9d0333f099c @@ -16091,7 +16143,7 @@ __metadata: languageName: node linkType: hard -"@types/d3-interpolate@npm:*, @types/d3-interpolate@npm:^3.0.4": +"@types/d3-interpolate@npm:*, @types/d3-interpolate@npm:^3.0.1, @types/d3-interpolate@npm:^3.0.4": version: 3.0.4 resolution: "@types/d3-interpolate@npm:3.0.4" dependencies: @@ -16135,7 +16187,7 @@ __metadata: languageName: node linkType: hard -"@types/d3-scale@npm:*": +"@types/d3-scale@npm:*, @types/d3-scale@npm:^4.0.2": version: 4.0.9 resolution: "@types/d3-scale@npm:4.0.9" dependencies: @@ -16151,12 +16203,12 @@ __metadata: languageName: node linkType: hard -"@types/d3-shape@npm:*": - version: 3.1.6 - resolution: "@types/d3-shape@npm:3.1.6" +"@types/d3-shape@npm:*, @types/d3-shape@npm:^3.1.0": + version: 3.1.8 + resolution: "@types/d3-shape@npm:3.1.8" dependencies: "@types/d3-path": "npm:*" - checksum: 10c0/0625715925d3c7ed3d44ce998b42c993f063c31605b6e4a8046c4be0fe724e2d214fc83e86d04f429a30a6e1f439053e92b0d9e59e1180c3a5327b4a6e79fa0a + checksum: 10c0/49ec2172b9eb66fc1d036e2a23966216bb972e9af51ddbed134df24bd71aedf207bb1ef81903a119eb4e1f5e927cf44beacaf64c9af86474e5548594b102b574 languageName: node linkType: hard @@ -16167,14 +16219,14 @@ __metadata: languageName: node linkType: hard -"@types/d3-time@npm:*": +"@types/d3-time@npm:*, @types/d3-time@npm:^3.0.0": version: 3.0.4 resolution: "@types/d3-time@npm:3.0.4" checksum: 10c0/6d9e2255d63f7a313a543113920c612e957d70da4fb0890931da6c2459010291b8b1f95e149a538500c1c99e7e6c89ffcce5554dd29a31ff134a38ea94b6d174 languageName: node linkType: hard -"@types/d3-timer@npm:*": +"@types/d3-timer@npm:*, @types/d3-timer@npm:^3.0.0": version: 3.0.2 resolution: "@types/d3-timer@npm:3.0.2" checksum: 10c0/c644dd9571fcc62b1aa12c03bcad40571553020feeb5811f1d8a937ac1e65b8a04b759b4873aef610e28b8714ac71c9885a4d6c127a048d95118f7e5b506d9e1 @@ -17089,6 +17141,13 @@ __metadata: languageName: node linkType: hard +"@types/use-sync-external-store@npm:^0.0.6": + version: 0.0.6 + resolution: "@types/use-sync-external-store@npm:0.0.6" + checksum: 10c0/77c045a98f57488201f678b181cccd042279aff3da34540ad242f893acc52b358bd0a8207a321b8ac09adbcef36e3236944390e2df4fcedb556ce7bb2a88f2a8 + languageName: node + linkType: hard + "@types/wait-on@npm:5.3.4": version: 5.3.4 resolution: "@types/wait-on@npm:5.3.4" @@ -22492,6 +22551,15 @@ __metadata: languageName: node linkType: hard +"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:^3.1.6": + version: 3.2.4 + resolution: "d3-array@npm:3.2.4" + dependencies: + internmap: "npm:1 - 2" + checksum: 10c0/08b95e91130f98c1375db0e0af718f4371ccacef7d5d257727fe74f79a24383e79aba280b9ffae655483ffbbad4fd1dec4ade0119d88c4749f388641c8bf8c50 + languageName: node + linkType: hard + "d3-color@npm:1 - 3": version: 3.1.0 resolution: "d3-color@npm:3.1.0" @@ -22516,14 +22584,21 @@ __metadata: languageName: node linkType: hard -"d3-ease@npm:1 - 3": +"d3-ease@npm:1 - 3, d3-ease@npm:^3.0.1": version: 3.0.1 resolution: "d3-ease@npm:3.0.1" checksum: 10c0/fec8ef826c0cc35cda3092c6841e07672868b1839fcaf556e19266a3a37e6bc7977d8298c0fcb9885e7799bfdcef7db1baaba9cd4dcf4bc5e952cf78574a88b0 languageName: node linkType: hard -"d3-interpolate@npm:1 - 3, d3-interpolate@npm:^3.0.1": +"d3-format@npm:1 - 3": + version: 3.1.2 + resolution: "d3-format@npm:3.1.2" + checksum: 10c0/0de452ae07585238e7f01607a7e0066665c34609652188b6ac7dc9f424f69465a425e07d16d79bd0e5955202ac7f241c66d0c76f68a79fc6f4857c94cf420652 + languageName: node + linkType: hard + +"d3-interpolate@npm:1 - 3, d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:^3.0.1": version: 3.0.1 resolution: "d3-interpolate@npm:3.0.1" dependencies: @@ -22532,6 +22607,26 @@ __metadata: languageName: node linkType: hard +"d3-path@npm:^3.1.0": + version: 3.1.0 + resolution: "d3-path@npm:3.1.0" + checksum: 10c0/dc1d58ec87fa8319bd240cf7689995111a124b141428354e9637aa83059eb12e681f77187e0ada5dedfce346f7e3d1f903467ceb41b379bfd01cd8e31721f5da + languageName: node + linkType: hard + +"d3-scale@npm:^4.0.2": + version: 4.0.2 + resolution: "d3-scale@npm:4.0.2" + dependencies: + d3-array: "npm:2.10.0 - 3" + d3-format: "npm:1 - 3" + d3-interpolate: "npm:1.2.0 - 3" + d3-time: "npm:2.1.1 - 3" + d3-time-format: "npm:2 - 4" + checksum: 10c0/65d9ad8c2641aec30ed5673a7410feb187a224d6ca8d1a520d68a7d6eac9d04caedbff4713d1e8545be33eb7fec5739983a7ab1d22d4e5ad35368c6729d362f1 + languageName: node + linkType: hard + "d3-selection@npm:2 - 3, d3-selection@npm:3, d3-selection@npm:^3.0.0": version: 3.0.0 resolution: "d3-selection@npm:3.0.0" @@ -22539,7 +22634,34 @@ __metadata: languageName: node linkType: hard -"d3-timer@npm:1 - 3": +"d3-shape@npm:^3.1.0": + version: 3.2.0 + resolution: "d3-shape@npm:3.2.0" + dependencies: + d3-path: "npm:^3.1.0" + checksum: 10c0/f1c9d1f09926daaf6f6193ae3b4c4b5521e81da7d8902d24b38694517c7f527ce3c9a77a9d3a5722ad1e3ff355860b014557b450023d66a944eabf8cfde37132 + languageName: node + linkType: hard + +"d3-time-format@npm:2 - 4": + version: 4.1.0 + resolution: "d3-time-format@npm:4.1.0" + dependencies: + d3-time: "npm:1 - 3" + checksum: 10c0/735e00fb25a7fd5d418fac350018713ae394eefddb0d745fab12bbff0517f9cdb5f807c7bbe87bb6eeb06249662f8ea84fec075f7d0cd68609735b2ceb29d206 + languageName: node + linkType: hard + +"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:^3.0.0": + version: 3.1.0 + resolution: "d3-time@npm:3.1.0" + dependencies: + d3-array: "npm:2 - 3" + checksum: 10c0/a984f77e1aaeaa182679b46fbf57eceb6ebdb5f67d7578d6f68ef933f8eeb63737c0949991618a8d29472dbf43736c7d7f17c452b2770f8c1271191cba724ca1 + languageName: node + linkType: hard + +"d3-timer@npm:1 - 3, d3-timer@npm:^3.0.1": version: 3.0.1 resolution: "d3-timer@npm:3.0.1" checksum: 10c0/d4c63cb4bb5461d7038aac561b097cd1c5673969b27cbdd0e87fa48d9300a538b9e6f39b4a7f0e3592ef4f963d858c8a9f0e92754db73116770856f2fc04561a @@ -22766,6 +22888,13 @@ __metadata: languageName: node linkType: hard +"decimal.js-light@npm:^2.5.1": + version: 2.5.1 + resolution: "decimal.js-light@npm:2.5.1" + checksum: 10c0/4fd33f535aac9e5bd832796831b65d9ec7914ad129c7437b3ab991b0c2eaaa5a57e654e6174c4a17f1b3895ea366f0c1ab4955cdcdf7cfdcf3ad5a58b456c020 + languageName: node + linkType: hard + "decimal.js@npm:^10.4.3": version: 10.6.0 resolution: "decimal.js@npm:10.6.0" @@ -23825,6 +23954,20 @@ __metadata: languageName: node linkType: hard +"es-toolkit@npm:^1.39.3": + version: 1.47.1 + resolution: "es-toolkit@npm:1.47.1" + dependenciesMeta: + "@trivago/prettier-plugin-sort-imports@4.3.0": + unplugged: true + prettier-plugin-sort-re-exports@0.0.1: + unplugged: true + vitepress-plugin-sandpack@1.1.4: + unplugged: true + checksum: 10c0/d6dff140a71e15d22209f8482f1ce34bab433f449e569c28b9c535963b18b2c3b89b00d7cf7156b5c74cace4c5f96283f0a5fee3be8802dd2cf7481da90cfe0a + languageName: node + linkType: hard + "es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.46, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14, es5-ext@npm:~0.10.2": version: 0.10.64 resolution: "es5-ext@npm:0.10.64" @@ -28111,6 +28254,20 @@ __metadata: languageName: node linkType: hard +"immer@npm:^10.1.1": + version: 10.2.0 + resolution: "immer@npm:10.2.0" + checksum: 10c0/35e66b0585b2aec4e85ae7a993f049405f170799ba89d79205bc3fdae2c5bdaa2b1d35f62803d8beee42b7e85c7f7315a6e93b6a5a510c5a46f03dbe63619e87 + languageName: node + linkType: hard + +"immer@npm:^11.0.0": + version: 11.1.8 + resolution: "immer@npm:11.1.8" + checksum: 10c0/df971d8a8f6a5312c6dca4a8437e20b3185d6c9cd6830ad526c18ffd50f4037ef8db4f332b0adbcb9f8c5ee2fbe117cf0623e8554e24777105b3cc9faf866d34 + languageName: node + linkType: hard + "immutable@npm:^5.0.2, immutable@npm:^5.1.5": version: 5.1.5 resolution: "immutable@npm:5.1.5" @@ -28277,6 +28434,13 @@ __metadata: languageName: node linkType: hard +"internmap@npm:1 - 2": + version: 2.0.3 + resolution: "internmap@npm:2.0.3" + checksum: 10c0/8cedd57f07bbc22501516fbfc70447f0c6812871d471096fad9ea603516eacc2137b633633daf432c029712df0baefd793686388ddf5737e3ea15074b877f7ed + languageName: node + linkType: hard + "interpret@npm:^1.0.0": version: 1.4.0 resolution: "interpret@npm:1.4.0" @@ -35979,6 +36143,25 @@ __metadata: languageName: node linkType: hard +"react-redux@npm:8.x.x || 9.x.x": + version: 9.3.0 + resolution: "react-redux@npm:9.3.0" + dependencies: + "@types/use-sync-external-store": "npm:^0.0.6" + use-sync-external-store: "npm:^1.4.0" + peerDependencies: + "@types/react": ^18.2.25 || ^19 + react: ^18.0 || ^19 + redux: ^5.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + redux: + optional: true + checksum: 10c0/b9f4efcfbfbc90cac9d1709ab3affb1e18a9dc9bd3cceda43bd2e1d9d2394ee0c29df36ec2202d52b566db774888b594c8c5aa86b64f27ef34fca607c687c9e3 + languageName: node + linkType: hard + "react-redux@npm:^7.2.0": version: 7.2.9 resolution: "react-redux@npm:7.2.9" @@ -36363,6 +36546,29 @@ __metadata: languageName: node linkType: hard +"recharts@npm:3.8.0": + version: 3.8.0 + resolution: "recharts@npm:3.8.0" + dependencies: + "@reduxjs/toolkit": "npm:^1.9.0 || 2.x.x" + clsx: "npm:^2.1.1" + decimal.js-light: "npm:^2.5.1" + es-toolkit: "npm:^1.39.3" + eventemitter3: "npm:^5.0.1" + immer: "npm:^10.1.1" + react-redux: "npm:8.x.x || 9.x.x" + reselect: "npm:5.1.1" + tiny-invariant: "npm:^1.3.3" + use-sync-external-store: "npm:^1.2.2" + victory-vendor: "npm:^37.0.2" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + checksum: 10c0/ae8e60202138670211a9464ecd838600803044796570281978f3d79d02c3add39d6513fd943c29d62a1bdefe01c0b98287e12a2a6685da3617257969c6ef2290 + languageName: node + linkType: hard + "rechoir@npm:^0.6.2": version: 0.6.2 resolution: "rechoir@npm:0.6.2" @@ -36477,6 +36683,15 @@ __metadata: languageName: node linkType: hard +"redux-thunk@npm:^3.1.0": + version: 3.1.0 + resolution: "redux-thunk@npm:3.1.0" + peerDependencies: + redux: ^5.0.0 + checksum: 10c0/21557f6a30e1b2e3e470933247e51749be7f1d5a9620069a3125778675ce4d178d84bdee3e2a0903427a5c429e3aeec6d4df57897faf93eb83455bc1ef7b66fd + languageName: node + linkType: hard + "redux@npm:^4.0.0, redux@npm:^4.0.4": version: 4.2.1 resolution: "redux@npm:4.2.1" @@ -36486,6 +36701,13 @@ __metadata: languageName: node linkType: hard +"redux@npm:^5.0.1": + version: 5.0.1 + resolution: "redux@npm:5.0.1" + checksum: 10c0/b10c28357194f38e7d53b760ed5e64faa317cc63de1fb95bc5d9e127fab956392344368c357b8e7a9bedb0c35b111e7efa522210cfdc3b3c75e5074718e9069c + languageName: node + linkType: hard + "refa@npm:^0.12.0, refa@npm:^0.12.1": version: 0.12.1 resolution: "refa@npm:0.12.1" @@ -36863,6 +37085,20 @@ __metadata: languageName: node linkType: hard +"reselect@npm:5.1.1": + version: 5.1.1 + resolution: "reselect@npm:5.1.1" + checksum: 10c0/219c30da122980f61853db3aebd173524a2accd4b3baec770e3d51941426c87648a125ca08d8c57daa6b8b086f2fdd2703cb035dd6231db98cdbe1176a71f489 + languageName: node + linkType: hard + +"reselect@npm:^5.1.0": + version: 5.2.0 + resolution: "reselect@npm:5.2.0" + checksum: 10c0/d0a8497e404b25a769fe792eacae88b9b576c30870450cd243d76ec9427d91a59c4a2cc00d824d283448b444c4c698a8f961d771c8ae39c759313afb31950e2e + languageName: node + linkType: hard + "resolve-alpn@npm:^1.0.0": version: 1.2.1 resolution: "resolve-alpn@npm:1.2.1" @@ -41269,6 +41505,28 @@ __metadata: languageName: node linkType: hard +"victory-vendor@npm:^37.0.2": + version: 37.3.6 + resolution: "victory-vendor@npm:37.3.6" + dependencies: + "@types/d3-array": "npm:^3.0.3" + "@types/d3-ease": "npm:^3.0.0" + "@types/d3-interpolate": "npm:^3.0.1" + "@types/d3-scale": "npm:^4.0.2" + "@types/d3-shape": "npm:^3.1.0" + "@types/d3-time": "npm:^3.0.0" + "@types/d3-timer": "npm:^3.0.0" + d3-array: "npm:^3.1.6" + d3-ease: "npm:^3.0.1" + d3-interpolate: "npm:^3.0.1" + d3-scale: "npm:^4.0.2" + d3-shape: "npm:^3.1.0" + d3-time: "npm:^3.0.0" + d3-timer: "npm:^3.0.1" + checksum: 10c0/0a9628db30b898160409628f26d457ba15adc86472531817d73fbeb847de498d94f91dee5f4caa969195744e91be93e100eeff7a392b591ac5349343a36dec29 + languageName: node + linkType: hard + "vite-plugin-dts@npm:4.5.4": version: 4.5.4 resolution: "vite-plugin-dts@npm:4.5.4" From da51cf89140d0fa991f18048f7114b9a516a818c Mon Sep 17 00:00:00 2001 From: Ciaran Morinan Date: Fri, 26 Jun 2026 14:14:21 +0100 Subject: [PATCH 02/21] update telemetry handling --- .env | 13 +- README.md | 7 +- apps/hash-api/README.md | 81 +------ apps/hash-api/package.json | 1 - .../analyses}/supply-chain.ts | 30 +-- .../analyses}/supply-chain/dataset.ts | 11 +- .../src/analysis/setup-analysis-handler.ts | 105 +++++++++ .../resolve-analysis.test.ts} | 94 ++++++-- .../resolve-analysis.ts | 218 ++++++++++++++++++ .../src/analysis/shared/analysis-registry.ts | 79 +++++++ .../src/{query => analysis}/shared/errors.ts | 12 +- .../shared/storage-key.test.ts | 33 ++- .../{query => analysis}/shared/storage-key.ts | 26 ++- .../hash-api/src/auth/create-auth-handlers.ts | 18 +- .../src/email/create-email-transporter.ts | 13 +- .../migrate-ontology-types.ts | 4 +- apps/hash-api/src/index.ts | 21 +- apps/hash-api/src/instrument.mjs | 4 +- apps/hash-api/src/lib/env-config.ts | 4 +- apps/hash-api/src/query.ts | 80 ------- apps/hash-api/src/query/resolve-query.ts | 171 -------------- .../src/query/shared/query-registry.ts | 81 ------- .../src/seed-data/seed-supply-chain-demo.ts | 9 +- .../src/telemetry/environment.test.ts | 33 +++ apps/hash-api/src/telemetry/environment.ts | 9 + apps/hash-api/src/telemetry/rudderstack.ts | 40 ---- apps/hash-api/src/telemetry/snowplow-setup.ts | 43 ---- .../src/telemetry/telemetry-endpoint.test.ts | 61 +++++ .../src/telemetry/telemetry-endpoint.ts | 112 +++++++++ apps/hash-api/src/telemetry/telemetry.ts | 214 +++++++++++++++++ .../src/lib/supply-chain/query-client.ts | 104 --------- apps/hash-frontend/src/pages/_app.page.tsx | 21 ++ .../index.page.tsx => supply-chain.page.tsx} | 6 +- .../product/[product-id].page.tsx | 0 .../shared/supply-chain-analysis-requests.ts} | 48 ++-- .../shared/supply-chain-layout.tsx | 2 +- .../site/[site-id].page.tsx | 0 .../[product-id]/[step-id].page.tsx | 0 .../src/shared/analysis-client.ts | 108 +++++++++ .../src/shared/telemetry-client.ts | 62 +++++ .../src/{query => analysis}/types.ts | 41 ++-- .../src/telemetry/types.ts | 53 +++++ yarn.lock | 30 --- 43 files changed, 1336 insertions(+), 766 deletions(-) rename apps/hash-api/src/{query/queries => analysis/analyses}/supply-chain.ts (76%) rename apps/hash-api/src/{query/queries => analysis/analyses}/supply-chain/dataset.ts (88%) create mode 100644 apps/hash-api/src/analysis/setup-analysis-handler.ts rename apps/hash-api/src/{query/resolve-query.test.ts => analysis/setup-analysis-handler/resolve-analysis.test.ts} (59%) create mode 100644 apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.ts create mode 100644 apps/hash-api/src/analysis/shared/analysis-registry.ts rename apps/hash-api/src/{query => analysis}/shared/errors.ts (65%) rename apps/hash-api/src/{query => analysis}/shared/storage-key.test.ts (66%) rename apps/hash-api/src/{query => analysis}/shared/storage-key.ts (53%) delete mode 100644 apps/hash-api/src/query.ts delete mode 100644 apps/hash-api/src/query/resolve-query.ts delete mode 100644 apps/hash-api/src/query/shared/query-registry.ts create mode 100644 apps/hash-api/src/telemetry/environment.test.ts create mode 100644 apps/hash-api/src/telemetry/environment.ts delete mode 100644 apps/hash-api/src/telemetry/rudderstack.ts delete mode 100644 apps/hash-api/src/telemetry/snowplow-setup.ts create mode 100644 apps/hash-api/src/telemetry/telemetry-endpoint.test.ts create mode 100644 apps/hash-api/src/telemetry/telemetry-endpoint.ts create mode 100644 apps/hash-api/src/telemetry/telemetry.ts delete mode 100644 apps/hash-frontend/src/lib/supply-chain/query-client.ts rename apps/hash-frontend/src/pages/{supply-chain/index.page.tsx => supply-chain.page.tsx} (69%) rename apps/hash-frontend/src/pages/{supply-chain => supply-chain.page}/product/[product-id].page.tsx (100%) rename apps/hash-frontend/src/{lib/supply-chain/data.ts => pages/supply-chain.page/shared/supply-chain-analysis-requests.ts} (73%) rename apps/hash-frontend/src/pages/{supply-chain => supply-chain.page}/shared/supply-chain-layout.tsx (96%) rename apps/hash-frontend/src/pages/{supply-chain => supply-chain.page}/site/[site-id].page.tsx (100%) rename apps/hash-frontend/src/pages/{supply-chain => supply-chain.page}/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx (100%) create mode 100644 apps/hash-frontend/src/shared/analysis-client.ts create mode 100644 apps/hash-frontend/src/shared/telemetry-client.ts rename libs/@local/hash-isomorphic-utils/src/{query => analysis}/types.ts (56%) create mode 100644 libs/@local/hash-isomorphic-utils/src/telemetry/types.ts diff --git a/.env b/.env index 750161cb8f8..8c938470415 100644 --- a/.env +++ b/.env @@ -69,14 +69,11 @@ API_ORIGIN=http://localhost:5001 # @todo H-124 implement a new change subscription service ENABLE_REALTIME_SYNC=false -# Optional usage telemetry for HASH -HASH_TELEMETRY_ENABLED=false -# Currently our endpoint doesn't have HTTPS so this is set to false -HASH_TELEMETRY_HTTPS=false -# DNS collector endpoint -HASH_TELEMETRY_DESTINATION=REPLACE_ME.aws.com -# Is used for differentiating different apps, can be any value -HASH_TELEMETRY_APP_ID=hash-app +# Optional product analytics via Rudderstack. Leave the write key blank to +# disable telemetry (it is also disabled automatically on localhost). Use a +# separate write key per environment; the environment label sent with events is +# derived from ENVIRONMENT (production/staging, otherwise development). +HASH_API_RUDDERSTACK_KEY= ########################################### # Disable telemetry from third-party dependencies who transmit IP addresses diff --git a/README.md b/README.md index 0f23b7ded29..8cd2238c2b5 100644 --- a/README.md +++ b/README.md @@ -294,12 +294,9 @@ The Postgres information for the graph query layer is configured through: - `HASH_REDIS_HOST` (default: `localhost`) - `HASH_REDIS_PORT` (default: `6379`) -#### Snowplow telemetry +#### Rudderstack telemetry -- `HASH_TELEMETRY_ENABLED`: whether Snowplow is used or not. `true` or `false`. (default: `false`) -- `HASH_TELEMETRY_HTTPS`: set to "1" to connect to the Snowplow over an HTTPS connection. `true` or `false`. (default: `false`) -- `HASH_TELEMETRY_DESTINATION`: the hostname of the Snowplow tracker endpoint to connect to. (required) -- `HASH_TELEMETRY_APP_ID`: ID used to differentiate application by. Can be any string. (default: `hash-workspace-app`) +- `HASH_API_RUDDERSTACK_KEY`: Rudderstack write key for product analytics. Leave blank to disable telemetry. The `environment` label on events is derived from `ENVIRONMENT`. (optional) #### Others diff --git a/apps/hash-api/README.md b/apps/hash-api/README.md index 844f926fd98..9643e30bab8 100644 --- a/apps/hash-api/README.md +++ b/apps/hash-api/README.md @@ -47,11 +47,7 @@ The HASH Backend API service is configured using the following environment varia - `STATSD_HOST`: the hostname of the StatsD server. - `STATSD_PORT`: (default: 8125) the port number the StatsD server is listening on. - `HASH_INTEGRATION_QUEUE_NAME` The name of the Redis queue which updates to entities are published to used to decide what changes should be written to connected applications (for two-way sync between them and HASH) -- Snowplow telemetry: - - `HASH_TELEMETRY_ENABLED`: (default: `false`) whether Snowplow is used or not. `true` or `false`. - - `HASH_TELEMETRY_HTTPS`: (default: `false`) set to "1" to connect to the Snowplow over an HTTPS connection. `true` or `false`. - - `HASH_TELEMETRY_DESTINATION`: (required) the hostname of the Snowplow tracker endpoint to connect to. - - `HASH_TELEMETRY_APP_ID`: ID used to differentiate application by. Can be any string. +- `HASH_API_RUDDERSTACK_KEY`: (optional) Rudderstack write key for product analytics. Leave blank to disable telemetry. The environment label sent with events is derived from `ENVIRONMENT`. ## Metrics @@ -65,75 +61,10 @@ this enabled, from the root of the repo, execute: yarn serve:hash-backend-statsd ``` -## Snowplow +## Telemetry -The API may use Snowplow to collect structured behavioural data. In order to use Snowplow -the `HASH_TELEMETRY_*` environment values should be specified, most importantly -`HASH_TELEMETRY_DESTINATION` should point to a snowplow tracker endpoint and -`HASH_TELEMETRY_ENABLED=true`. +The API sends product-analytics events to [Rudderstack](https://www.rudderstack.com/). +Telemetry is enabled only when `HASH_API_RUDDERSTACK_KEY` is set. -To set up a local Snowplow deployment, [Snowplow mini](https://github.com/snowplow/snowplow-mini) can be used. This requires [Vagrant](https://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/) to be installed. -By default, the Snowplow mini instance uses a fair bit of RAM and CPU. -Snowplow mini exposes a lot of ports to the host through the default [Vagrantfile](https://github.com/snowplow/snowplow-mini/blob/f7dbf73f1e3ba589d2dd1d8b94589c4f610dba1f/Vagrantfile). To make the instance play well wit HASH, comment out the following in the Snowplow mini Vagrantfile: - -```ruby -#... - config.vm.network "forwarded_port", guest: 80, host: 2000 - # config.vm.network "forwarded_port", guest: 3000, host: 3000 - config.vm.network "forwarded_port", guest: 4171, host: 4171 - config.vm.network "forwarded_port", guest: 8080, host: 8080 - config.vm.network "forwarded_port", guest: 8093, host: 8093 - config.vm.network "forwarded_port", guest: 9200, host: 9200 - config.vm.network "forwarded_port", guest: 5601, host: 5601 - # config.vm.network "forwarded_port", guest: 8081, host: 8081 - config.vm.network "forwarded_port", guest: 10000, host: 10000 -#... -``` - -The default credentials for the basic auth at [http://localhost:2000/home](http://localhost:2000/home) for the local Snowplow mini instance is: - -- username: USERNAME_PLACEHOLDER -- password: PASSWORD_PLACEHOLDER - -With a local Snowplow deployment, the following destination can be used in the HASH env: -`HASH_TELEMETRY_DESTINATION=localhost:2000` - -### Troubleshooting Vagrant/VirtualBox - -On a fresh install of Vagrant/VirtualBox, some kernel modules might be unloaded for VirtualBox -which makes the `vagrant up` command error out on various steps along the way. -It might be necessary to load the following kernel modules to prevent errors: - -Linux: - -```sh -sudo modprobe vboxnetflt -sudo modprobe vboxnetadp -sudo modprobe vboxdrv -``` - -macOS: - -```sh -sudo kmutil load -b org.virtualbox.kext.VBoxNetFlt -sudo kmutil load -b org.virtualbox.kext.VBoxNetAdp -sudo kmutil load -b org.virtualbox.kext.VBoxDrv -``` - -If you encounter an error such as -`mount.nfs: access denied by server while mounting ...` -It might be necessary to make the following changes to the Snowplow mini Vagrantfile to disable NFS. - -```ruby - # Use NFS for shared folders for better performance - # config.vm.network :private_network, ip: '192.168.56.56' # Uncomment to use NFS - config.vm.synced_folder '.', '/vagrant' #, nfs: true # Uncomment to use NFS -``` - -Here the `config.vm.network` line and the `, nfs: true` argument are commented out. - -If you see `uninitialized constant VagrantPlugins::HostDarwin::Cap::Version` on MacOS, see [this issue](https://github.com/hashicorp/vagrant/issues/12583). - -If you encounter an issue on the `npm install` step (5), try commenting out lines 8 & 9 of the Vagrantfile (i.e. disable using NFS for shared folders). - -You may need to run `vagrant reload --provision` after applying fixes. +The `environment` property attached to every event is derived from `ENVIRONMENT` (`production` / `staging`, +otherwise `development`). diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index 3714ebdb62b..7062103f72d 100644 --- a/apps/hash-api/package.json +++ b/apps/hash-api/package.json @@ -65,7 +65,6 @@ "@ory/kratos-client": "25.4.0", "@rudderstack/rudder-sdk-node": "3.0.8", "@sentry/node": "10.54.0", - "@snowplow/node-tracker": "4.8.2", "@temporalio/client": "1.18.1", "@temporalio/proto": "1.18.1", "@types/ws": "8.18.1", diff --git a/apps/hash-api/src/query/queries/supply-chain.ts b/apps/hash-api/src/analysis/analyses/supply-chain.ts similarity index 76% rename from apps/hash-api/src/query/queries/supply-chain.ts rename to apps/hash-api/src/analysis/analyses/supply-chain.ts index 126d1615e93..eb8b4647df3 100644 --- a/apps/hash-api/src/query/queries/supply-chain.ts +++ b/apps/hash-api/src/analysis/analyses/supply-chain.ts @@ -1,14 +1,14 @@ -import { QueryNotFoundError } from "../shared/errors"; +import { AnalysisNotFoundError } from "../shared/errors"; import { requireSlugArg } from "../shared/storage-key"; import { resolveDataset } from "./supply-chain/dataset"; -import type { NamedQuery } from "../shared/query-registry"; +import type { NamedAnalysis } from "../shared/analysis-registry"; /** - * Named queries backing the value-chain-timing views. Every query is scoped to + * Named analyses backing the supply chain views. Every analysis is scoped to * a single web (the dataset owner) and resolves to one or more JSON artifacts. * - * Storage layout (under `supply-chain/{webId}/{version}/`): + * Storage layout (under `{webId}/supply-chain/{version}/`): * products.json * sites.json * {productId}/graph.json @@ -18,7 +18,7 @@ import type { NamedQuery } from "../shared/query-registry"; * site/{siteId}/summary.json */ -const listProducts: NamedQuery = { +const listProducts: NamedAnalysis = { name: "listProducts", resolve: async (ctx) => { const { base } = await resolveDataset(ctx); @@ -29,7 +29,7 @@ const listProducts: NamedQuery = { }, }; -const listSites: NamedQuery = { +const listSites: NamedAnalysis = { name: "listSites", resolve: async (ctx) => { const { base } = await resolveDataset(ctx); @@ -40,14 +40,14 @@ const listSites: NamedQuery = { }, }; -const productGraph: NamedQuery = { +const productGraph: NamedAnalysis = { name: "productGraph", resolve: async (ctx) => { const productId = requireSlugArg(ctx.args, "productId"); const { base, manifest } = await resolveDataset(ctx); if (!manifest.products.includes(productId)) { - throw new QueryNotFoundError(`Unknown product "${productId}"`); + throw new AnalysisNotFoundError(`Unknown product "${productId}"`); } return { @@ -57,7 +57,7 @@ const productGraph: NamedQuery = { }, }; -const stepDetail: NamedQuery = { +const stepDetail: NamedAnalysis = { name: "stepDetail", resolve: async (ctx) => { const productId = requireSlugArg(ctx.args, "productId"); @@ -65,10 +65,10 @@ const stepDetail: NamedQuery = { const { base, manifest } = await resolveDataset(ctx); if (!manifest.products.includes(productId)) { - throw new QueryNotFoundError(`Unknown product "${productId}"`); + throw new AnalysisNotFoundError(`Unknown product "${productId}"`); } if (!(manifest.steps[productId] ?? []).includes(stepId)) { - throw new QueryNotFoundError( + throw new AnalysisNotFoundError( `Unknown step "${stepId}" for product "${productId}"`, ); } @@ -82,7 +82,7 @@ const stepDetail: NamedQuery = { }, }; -const supplierPerformance: NamedQuery = { +const supplierPerformance: NamedAnalysis = { name: "supplierPerformance", resolve: async (ctx) => { const { base } = await resolveDataset(ctx); @@ -99,14 +99,14 @@ const supplierPerformance: NamedQuery = { }, }; -const siteSummary: NamedQuery = { +const siteSummary: NamedAnalysis = { name: "siteSummary", resolve: async (ctx) => { const siteId = requireSlugArg(ctx.args, "siteId"); const { base, manifest } = await resolveDataset(ctx); if (!manifest.sites.includes(siteId)) { - throw new QueryNotFoundError(`Unknown site "${siteId}"`); + throw new AnalysisNotFoundError(`Unknown site "${siteId}"`); } return { @@ -118,7 +118,7 @@ const siteSummary: NamedQuery = { }, }; -export const supplyChainQueries: readonly NamedQuery[] = [ +export const supplyChainAnalyses: readonly NamedAnalysis[] = [ listProducts, listSites, productGraph, diff --git a/apps/hash-api/src/query/queries/supply-chain/dataset.ts b/apps/hash-api/src/analysis/analyses/supply-chain/dataset.ts similarity index 88% rename from apps/hash-api/src/query/queries/supply-chain/dataset.ts rename to apps/hash-api/src/analysis/analyses/supply-chain/dataset.ts index 9488ea3a9f7..583069cbb03 100644 --- a/apps/hash-api/src/query/queries/supply-chain/dataset.ts +++ b/apps/hash-api/src/analysis/analyses/supply-chain/dataset.ts @@ -1,6 +1,7 @@ import { DatasetUnavailableError } from "../../shared/errors"; +import { webScopedKey } from "../../shared/storage-key"; -import type { QueryResolutionContext } from "../../shared/query-registry"; +import type { AnalysisResolutionContext } from "../../shared/analysis-registry"; import type { WebId } from "@blockprotocol/type-system"; /** Top-level storage namespace for all supply-chain analysis artifacts. */ @@ -18,7 +19,7 @@ export interface DatasetPointer { /** * Manifest enumerating every valid id in a published dataset. Used both to * validate client-supplied ids (so only known artifacts are resolvable) and to - * answer list-style queries' membership checks. + * answer list-style analyses' membership checks. */ export interface SupplyChainManifest { datasetVersion: string; @@ -29,10 +30,10 @@ export interface SupplyChainManifest { } export const datasetPointerKey = (webId: WebId): string => - `${SUPPLY_CHAIN_NAMESPACE}/${webId}/current.json`; + webScopedKey(webId, SUPPLY_CHAIN_NAMESPACE, "current.json"); export const datasetBaseKey = (webId: WebId, version: string): string => - `${SUPPLY_CHAIN_NAMESPACE}/${webId}/${version}`; + webScopedKey(webId, SUPPLY_CHAIN_NAMESPACE, version); export const manifestKey = (webId: WebId, version: string): string => `${datasetBaseKey(webId, version)}/manifest.json`; @@ -50,7 +51,7 @@ const parseJson = (buffer: Buffer, what: string): T => { * {@link DatasetUnavailableError} if the web has no published dataset. */ export const resolveDataset = async ( - ctx: QueryResolutionContext, + ctx: AnalysisResolutionContext, ): Promise<{ version: string; base: string; diff --git a/apps/hash-api/src/analysis/setup-analysis-handler.ts b/apps/hash-api/src/analysis/setup-analysis-handler.ts new file mode 100644 index 00000000000..e4135c34e09 --- /dev/null +++ b/apps/hash-api/src/analysis/setup-analysis-handler.ts @@ -0,0 +1,105 @@ +import { ipKeyGenerator, rateLimit } from "express-rate-limit"; + +import { telemetry } from "../telemetry/telemetry"; +import { supplyChainAnalyses } from "./analyses/supply-chain"; +import { resolveInvocation } from "./setup-analysis-handler/resolve-analysis"; +import { registerAnalyses } from "./shared/analysis-registry"; + +import type { + AnalysisRequest, + AnalysisResponse, +} from "@local/hash-isomorphic-utils/analysis/types"; +import type { Express } from "express"; +import type Keyv from "keyv"; + +/** Upper bound on invocations per batch request, to bound work per call. */ +const MAX_BATCH_SIZE = 25; + +/** + * Per-IP rate limiter for the analysis gateway. A single request fans out to up + * to {@link MAX_BATCH_SIZE} invocations, each authorising against its scoped + * webs and reading from storage, so the endpoint is an amplifier that must be + * bounded. Authenticated callers get a higher ceiling than anonymous ones. + */ +const analysisRateLimiter = rateLimit({ + windowMs: process.env.NODE_ENV === "test" ? 10 : 1000 * 60, // 1 minute + limit: (req) => (req.user ? 240 : 30), + standardHeaders: true, + legacyHeaders: false, + keyGenerator: (req) => (req.ip ? ipKeyGenerator(req.ip) : "ip-unavailable"), +}); + +let analysesRegistered = false; + +/** + * Register the built-in named analyses. Idempotent so repeated setup calls (e.g. + * across test harness reinitialisation) don't throw on duplicate registration. + */ +const ensureAnalysesRegistered = () => { + if (analysesRegistered) { + return; + } + registerAnalyses(supplyChainAnalyses); + analysesRegistered = true; +}; + +/** + * Mounts the generic analysis gateway at `POST /api/analysis`. + * + * The gateway is a thin control plane: it authenticates the caller, authorises + * each invocation against its scoped web(s), resolves named analyses to stored + * artifacts, and returns short-lived URLs the client fetches directly from + * storage (the data plane). Artifact bytes never pass through the API. + */ +export const setupAnalysisHandler = (app: Express, cache: Keyv) => { + ensureAnalysesRegistered(); + + app.post("/api/analysis", analysisRateLimiter, async (req, res) => { + const { user } = req; + if (!user) { + res.status(401).json({ error: "Authentication required" }); + return; + } + + const body = req.body as AnalysisRequest | undefined; + if (!body || !Array.isArray(body.requests)) { + res.status(400).json({ + error: "Request body must be { requests: AnalysisInvocation[] }", + }); + return; + } + + if (body.requests.length > MAX_BATCH_SIZE) { + res + .status(400) + .json({ error: `Too many requests (max ${MAX_BATCH_SIZE})` }); + return; + } + + const { graphApi, uploadProvider } = req.context; + + const results = await Promise.all( + body.requests.map((invocation) => + resolveInvocation({ + invocation, + actorId: user.accountId, + graphApi, + uploadProvider, + cache, + }), + ), + ); + + for (const [index, result] of results.entries()) { + const invocation = body.requests[index]!; + telemetry.track(req, "analysis_run", { + analysis: invocation.analysis, + webId: invocation.webId, + status: result.status, + artifactCount: result.artifacts?.length ?? 0, + }); + } + + res.json({ results } satisfies AnalysisResponse); + }); +}; diff --git a/apps/hash-api/src/query/resolve-query.test.ts b/apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.test.ts similarity index 59% rename from apps/hash-api/src/query/resolve-query.test.ts rename to apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.test.ts index d1c506e96bb..46be9f99c2c 100644 --- a/apps/hash-api/src/query/resolve-query.test.ts +++ b/apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.test.ts @@ -12,21 +12,24 @@ vi.mock("@local/hash-graph-sdk/principal/actor-group", () => ({ getActorGroupRole: vi.fn(), })); -vi.mock("../logger", () => ({ +vi.mock("../../logger", () => ({ logger: { warn: vi.fn(), error: vi.fn(), info: vi.fn() }, })); import { getActorGroupRole } from "@local/hash-graph-sdk/principal/actor-group"; -import { supplyChainQueries } from "./queries/supply-chain"; -import { resolveInvocation } from "./resolve-query"; -import { clearQueryRegistry, registerQueries } from "./shared/query-registry"; +import { supplyChainAnalyses } from "../analyses/supply-chain"; +import { + clearAnalysisRegistry, + registerAnalyses, +} from "../shared/analysis-registry"; +import { resolveInvocation } from "./resolve-analysis"; -import type { GraphApi } from "../graph/context-types"; +import type { GraphApi } from "../../graph/context-types"; const mockedGetRole = vi.mocked(getActorGroupRole); -const WEB_ID = "web-test" as WebId; +const WEB_ID = "00000000-0000-4000-8000-000000000001" as WebId; const ACTOR_ID = "actor-test" as ActorEntityUuid; const VERSION = "2026-06-15"; @@ -38,10 +41,10 @@ const manifest = { }; const storedFiles: Record = { - [`supply-chain/${WEB_ID}/current.json`]: JSON.stringify({ + [`${WEB_ID}/supply-chain/current.json`]: JSON.stringify({ datasetVersion: VERSION, }), - [`supply-chain/${WEB_ID}/${VERSION}/manifest.json`]: JSON.stringify(manifest), + [`${WEB_ID}/supply-chain/${VERSION}/manifest.json`]: JSON.stringify(manifest), }; const uploadProvider = { @@ -62,22 +65,22 @@ const cache = { } as unknown as Keyv; const resolve = ( - query: string, + analysis: string, args: Record = {}, - webIds: WebId[] = [WEB_ID], + webId: WebId = WEB_ID, ) => resolveInvocation({ - invocation: { id: "test", query, args, webIds }, + invocation: { id: "test", analysis, args, webId }, actorId: ACTOR_ID, graphApi: {} as GraphApi, uploadProvider, cache, }); -describe("resolveInvocation (supply-chain queries)", () => { +describe("resolveInvocation (supply-chain analyses)", () => { beforeEach(() => { - clearQueryRegistry(); - registerQueries(supplyChainQueries); + clearAnalysisRegistry(); + registerAnalyses(supplyChainAnalyses); mockedGetRole.mockReset(); mockedGetRole.mockResolvedValue("member" as RoleName); }); @@ -93,6 +96,7 @@ describe("resolveInvocation (supply-chain queries)", () => { expect(result.artifacts![0]!.url).toContain( `${VERSION}/democat-x100-extr/graph.json`, ); + expect(result.artifacts![0]!.expiresAt).toBeDefined(); }); it("resolves stepDetail when the step is in the manifest", async () => { @@ -138,15 +142,69 @@ describe("resolveInvocation (supply-chain queries)", () => { expect(result.error).toMatch(/access/i); }); - it("errors for an unknown query name", async () => { - const result = await resolve("noSuchQuery"); + it("errors for an unknown analysis name", async () => { + const result = await resolve("noSuchAnalysis"); expect(result.status).toBe("error"); - expect(result.error).toMatch(/unknown query/i); + expect(result.error).toMatch(/unknown analysis/i); }); it("errors when no webId is supplied", async () => { - const result = await resolve("listProducts", {}, []); + const result = await resolveInvocation({ + invocation: { + id: "test", + analysis: "listProducts", + webId: undefined as unknown as WebId, + }, + actorId: ACTOR_ID, + graphApi: {} as GraphApi, + uploadProvider, + cache, + }); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/webId/i); + }); + + it("rejects a non-UUID webId before authorising", async () => { + const result = await resolve("listProducts", {}, "not-a-uuid" as WebId); expect(result.status).toBe("error"); expect(result.error).toMatch(/webId/i); + expect(mockedGetRole).not.toHaveBeenCalled(); + }); + + it("rejects non-object args", async () => { + const result = await resolveInvocation({ + invocation: { + id: "test", + analysis: "listProducts", + args: [] as unknown as Record, + webId: WEB_ID, + }, + actorId: ACTOR_ID, + graphApi: {} as GraphApi, + uploadProvider, + cache, + }); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/args must be an object/i); + }); + + it("refuses to presign an artifact key outside the authorised web", async () => { + const otherWebId = "00000000-0000-4000-8000-000000000002"; + clearAnalysisRegistry(); + registerAnalyses([ + { + name: "escaping", + resolve: async () => ({ + status: "ready", + artifacts: [ + { name: "leak", key: `${otherWebId}/supply-chain/secret.json` }, + ], + }), + }, + ]); + + const result = await resolve("escaping"); + expect(result.status).toBe("error"); + expect(result.error).toMatch(/internal error/i); }); }); diff --git a/apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.ts b/apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.ts new file mode 100644 index 00000000000..6516a1d886b --- /dev/null +++ b/apps/hash-api/src/analysis/setup-analysis-handler/resolve-analysis.ts @@ -0,0 +1,218 @@ +import { getActorGroupRole } from "@local/hash-graph-sdk/principal/actor-group"; + +import { logger } from "../../logger"; +import { getAnalysis } from "../shared/analysis-registry"; +import { + AnalysisArgError, + AnalysisNotFoundError, + DatasetUnavailableError, +} from "../shared/errors"; + +import type { GraphApi } from "../../graph/context-types"; +import type { ActorEntityUuid } from "@blockprotocol/type-system"; +import type { FileStorageProvider } from "@local/hash-backend-utils/file-storage"; +import type { + AnalysisInvocation, + AnalysisResult, +} from "@local/hash-isomorphic-utils/analysis/types"; +import type Keyv from "keyv"; + +/** + * Presigned URLs are short-lived: the frontend re-runs the gateway when a URL + * nears expiry rather than holding long-lived credentials. We cache the URL + * (minus an offset) so repeat invocations within the window are cheap. + */ +const ANALYSIS_URL_EXPIRATION_SECONDS = 60 * 60; +const ANALYSIS_URL_CACHE_OFFSET_SECONDS = 60 * 5; + +/** + * Web ids are UUIDs. Validating shape before they reach authorisation or storage + * key construction is cheap defence-in-depth (and yields clearer errors than a + * downstream failure on a malformed id). + */ +const UUID_PATTERN = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + +const isValidWebId = (value: unknown): value is string => + typeof value === "string" && UUID_PATTERN.test(value); + +/** Internal sentinel for an authorisation failure on a specific web. */ +class WebAuthorisationError extends Error {} + +/** Cached presign payload: the URL plus its true expiry. */ +interface CachedPresign { + url: string; + expiresAt: string; +} + +export interface ResolveInvocationParams { + invocation: AnalysisInvocation; + actorId: ActorEntityUuid; + graphApi: GraphApi; + uploadProvider: FileStorageProvider; + cache: Keyv; +} + +export const resolveInvocation = async ({ + invocation, + actorId, + graphApi, + uploadProvider, + cache, +}: ResolveInvocationParams): Promise => { + const id = typeof invocation.id === "string" ? invocation.id : ""; + const analysisName = invocation.analysis; + const webId = invocation.webId; + + const asResult = (partial: Omit): AnalysisResult => ({ + id, + ...partial, + }); + + if (typeof analysisName !== "string" || analysisName.length === 0) { + return asResult({ status: "error", error: "Missing analysis name" }); + } + + const analysis = getAnalysis(analysisName); + if (!analysis) { + return asResult({ + status: "error", + error: `Unknown analysis "${analysisName}"`, + }); + } + + if (!isValidWebId(webId)) { + return asResult({ status: "error", error: "A valid webId is required" }); + } + + // `args` is untrusted wire input, so validate its runtime shape rather than + // trusting the declared type. + const rawArgs: unknown = invocation.args; + if ( + rawArgs !== undefined && + (typeof rawArgs !== "object" || rawArgs === null || Array.isArray(rawArgs)) + ) { + return asResult({ status: "error", error: "args must be an object" }); + } + const args = (rawArgs ?? {}) as Record; + + const requiredRole = analysis.requiredWebRole ?? "member"; + + /** + * Every artifact key an analysis resolves to must live under the authorised + * web. Keys are built via `webScopedKey`, which puts the web id first, so an + * exact segment-0 match enforces that a (buggy or compromised) analysis cannot + * presign an object outside the caller's web. `resolve()` is otherwise + * free-form. + */ + const keyWithinAuthorisedWeb = (key: string): boolean => + key.split("/")[0] === webId; + + try { + const role = await getActorGroupRole( + graphApi, + { actorId }, + { actorId, actorGroupId: webId }, + ); + + if (!role) { + throw new WebAuthorisationError(`You do not have access to web ${webId}`); + } + + if (requiredRole === "administrator" && role !== "administrator") { + throw new WebAuthorisationError( + `Administrator role required in web ${webId}`, + ); + } + + const loadArtifact = async (key: string): Promise => { + try { + return await uploadProvider.downloadDirect({ key }); + } catch { + return null; + } + }; + + const resolution = await analysis.resolve({ + webId, + args, + loadArtifact, + }); + + if (resolution.status === "computing") { + return asResult({ + status: "computing", + retryAfterMs: resolution.retryAfterMs ?? 1000, + }); + } + + const refs = resolution.artifacts ?? []; + + const escapingRef = refs.find((ref) => !keyWithinAuthorisedWeb(ref.key)); + if (escapingRef) { + logger.error( + `Analysis "${analysisName}" resolved an artifact key outside the authorised webs [key=${escapingRef.key}]`, + ); + return asResult({ status: "error", error: "Internal error" }); + } + + const artifacts = await Promise.all( + refs.map(async (ref) => { + const cacheKey = `analysis-presign:${ref.key}`; + let cached = await cache.get(cacheKey); + + if (!cached) { + const url = await uploadProvider.presignDownloadByKey({ + key: ref.key, + expiresInSeconds: ANALYSIS_URL_EXPIRATION_SECONDS, + }); + cached = { + url, + expiresAt: new Date( + Date.now() + ANALYSIS_URL_EXPIRATION_SECONDS * 1000, + ).toISOString(), + }; + + try { + await cache.set( + cacheKey, + cached, + (ANALYSIS_URL_EXPIRATION_SECONDS - + ANALYSIS_URL_CACHE_OFFSET_SECONDS) * + 1000, + ); + } catch (error) { + logger.warn( + `Could not cache presigned analysis URL [key=${ref.key}]: ${error}`, + ); + } + } + + return { + name: ref.name, + format: ref.format ?? "json", + url: cached.url, + expiresAt: cached.expiresAt, + }; + }), + ); + + return asResult({ status: "ready", artifacts }); + } catch (error) { + if ( + error instanceof WebAuthorisationError || + error instanceof AnalysisArgError || + error instanceof AnalysisNotFoundError || + error instanceof DatasetUnavailableError + ) { + return asResult({ status: "error", error: error.message }); + } + + logger.error( + `Unexpected error resolving analysis "${analysisName}": ${ + error instanceof Error ? error.stack : String(error) + }`, + ); + return asResult({ status: "error", error: "Internal error" }); + } +}; diff --git a/apps/hash-api/src/analysis/shared/analysis-registry.ts b/apps/hash-api/src/analysis/shared/analysis-registry.ts new file mode 100644 index 00000000000..ed6df6daa34 --- /dev/null +++ b/apps/hash-api/src/analysis/shared/analysis-registry.ts @@ -0,0 +1,79 @@ +import type { RoleName, WebId } from "@blockprotocol/type-system"; + +/** + * Reference to a stored artifact that a named analysis resolves to. The gateway + * turns each into a short-lived, directly-fetchable URL. + */ +export interface ArtifactKeyRef { + /** Logical name within the analysis result, e.g. `"graph"`. */ + name: string; + /** Storage key, relative to the provider's default location. */ + key: string; + /** Wire format hint surfaced to the client (defaults to `"json"`). */ + format?: string; +} + +/** Context handed to a named analysis when resolving an invocation. */ +export interface AnalysisResolutionContext { + /** + * The (already authorised) web the analysis is scoped to. Artifacts the + * analysis resolves must live under this web's storage prefix. + */ + webId: WebId; + /** Validated-as-an-object analysis arguments (may be empty). */ + args: Record; + /** + * Read a stored artifact's raw bytes by key, e.g. to load a dataset pointer + * or manifest during resolution. Returns `null` if the object is missing. + */ + loadArtifact: (key: string) => Promise; +} + +/** The outcome of resolving a single invocation. */ +export interface AnalysisResolution { + status: "ready" | "computing"; + /** Present when `status === "ready"`. */ + artifacts?: ArtifactKeyRef[]; + /** Present when `status === "computing"`: client poll hint. */ + retryAfterMs?: number; +} + +/** + * A server-registered analysis. Each analysis owns its own argument validation + * and (where relevant) dataset/manifest membership checks, keeping the gateway + * and registry domain-agnostic. + */ +export interface NamedAnalysis { + /** Unique name clients reference, e.g. `"productGraph"`. */ + name: string; + /** + * Minimum role the actor must hold in the scoped web. Defaults to `"member"` + * (any web role grants access). + */ + requiredWebRole?: RoleName; + resolve: (ctx: AnalysisResolutionContext) => Promise; +} + +const registry = new Map(); + +/** Register a named analysis. Throws if the name is already taken. */ +export const registerAnalysis = (analysis: NamedAnalysis): void => { + if (registry.has(analysis.name)) { + throw new Error(`Analysis "${analysis.name}" is already registered`); + } + registry.set(analysis.name, analysis); +}; + +export const registerAnalyses = (analyses: readonly NamedAnalysis[]): void => { + for (const analysis of analyses) { + registerAnalysis(analysis); + } +}; + +export const getAnalysis = (name: string): NamedAnalysis | undefined => + registry.get(name); + +/** Exposed for tests: clear all registered analyses. */ +export const clearAnalysisRegistry = (): void => { + registry.clear(); +}; diff --git a/apps/hash-api/src/query/shared/errors.ts b/apps/hash-api/src/analysis/shared/errors.ts similarity index 65% rename from apps/hash-api/src/query/shared/errors.ts rename to apps/hash-api/src/analysis/shared/errors.ts index bafb3b4dc15..83c78bd3f4f 100644 --- a/apps/hash-api/src/query/shared/errors.ts +++ b/apps/hash-api/src/analysis/shared/errors.ts @@ -1,25 +1,25 @@ /** - * Errors thrown while resolving a named query. The gateway maps each to an + * Errors thrown while resolving a named analysis. The gateway maps each to an * appropriate per-result status (the batch request itself still returns 200). */ -/** Invalid or missing arguments for a query (maps to `error`, client fault). */ -export class QueryArgError extends Error { +/** Invalid or missing arguments for an analysis (maps to `error`, client fault). */ +export class AnalysisArgError extends Error { public readonly code = "INVALID_ARGS"; constructor(message: string) { super(message); - this.name = "QueryArgError"; + this.name = "AnalysisArgError"; } } /** A requested entity/artifact does not exist in the resolved dataset. */ -export class QueryNotFoundError extends Error { +export class AnalysisNotFoundError extends Error { public readonly code = "NOT_FOUND"; constructor(message: string) { super(message); - this.name = "QueryNotFoundError"; + this.name = "AnalysisNotFoundError"; } } diff --git a/apps/hash-api/src/query/shared/storage-key.test.ts b/apps/hash-api/src/analysis/shared/storage-key.test.ts similarity index 66% rename from apps/hash-api/src/query/shared/storage-key.test.ts rename to apps/hash-api/src/analysis/shared/storage-key.test.ts index d55bf039a6f..9adc3ce9ee8 100644 --- a/apps/hash-api/src/query/shared/storage-key.test.ts +++ b/apps/hash-api/src/analysis/shared/storage-key.test.ts @@ -1,7 +1,28 @@ import { describe, expect, it } from "vitest"; -import { QueryArgError } from "./errors"; -import { isValidSlug, optionalSlugArg, requireSlugArg } from "./storage-key"; +import { AnalysisArgError } from "./errors"; +import { + isValidSlug, + optionalSlugArg, + requireSlugArg, + webScopedKey, +} from "./storage-key"; + +import type { WebId } from "@blockprotocol/type-system"; + +describe("webScopedKey", () => { + const webId = "00000000-0000-4000-8000-000000000001" as WebId; + + it("puts the webId as the first path segment", () => { + const key = webScopedKey(webId, "supply-chain", "2026-06-15", "graph.json"); + expect(key).toBe(`${webId}/supply-chain/2026-06-15/graph.json`); + expect(key.split("/")[0]).toBe(webId); + }); + + it("works with just a namespace", () => { + expect(webScopedKey(webId, "supply-chain")).toBe(`${webId}/supply-chain`); + }); +}); describe("isValidSlug", () => { it("accepts typical product/site/step ids", () => { @@ -51,11 +72,11 @@ describe("requireSlugArg", () => { ).toBe("democat-x100-extr"); }); - it("throws QueryArgError for an invalid or missing slug", () => { + it("throws AnalysisArgError for an invalid or missing slug", () => { expect(() => requireSlugArg({ productId: "../x" }, "productId")).toThrow( - QueryArgError, + AnalysisArgError, ); - expect(() => requireSlugArg({}, "productId")).toThrow(QueryArgError); + expect(() => requireSlugArg({}, "productId")).toThrow(AnalysisArgError); }); }); @@ -70,7 +91,7 @@ describe("optionalSlugArg", () => { "demo-plant", ); expect(() => optionalSlugArg({ siteId: "a/b" }, "siteId")).toThrow( - QueryArgError, + AnalysisArgError, ); }); }); diff --git a/apps/hash-api/src/query/shared/storage-key.ts b/apps/hash-api/src/analysis/shared/storage-key.ts similarity index 53% rename from apps/hash-api/src/query/shared/storage-key.ts rename to apps/hash-api/src/analysis/shared/storage-key.ts index f0c2281f6a2..9c5448cf9ae 100644 --- a/apps/hash-api/src/query/shared/storage-key.ts +++ b/apps/hash-api/src/analysis/shared/storage-key.ts @@ -1,4 +1,22 @@ -import { QueryArgError } from "./errors"; +import { AnalysisArgError } from "./errors"; + +import type { WebId } from "@blockprotocol/type-system"; + +/** + * Build a storage key for a web-scoped artifact, with the `webId` as the first + * path segment followed by a namespace and any further parts. + * + * Putting the web id first makes it a tenant-isolation prefix: the analysis + * gateway authorises a resolved key by an exact segment-0 match (see + * `resolve-analysis.ts`), and storage policies/lifecycle rules can be scoped to + * a `{webId}/` prefix. All artifact keys MUST be built through this helper so + * that invariant holds. + */ +export const webScopedKey = ( + webId: WebId, + namespace: string, + ...parts: string[] +): string => [webId, namespace, ...parts].join("/"); /** * Slugs are the only values interpolated into storage keys from client input. @@ -11,8 +29,8 @@ export const isValidSlug = (value: unknown): value is string => typeof value === "string" && SLUG_PATTERN.test(value); /** - * Read a required slug argument, throwing {@link QueryArgError} if it is missing - * or fails validation. + * Read a required slug argument, throwing {@link AnalysisArgError} if it is + * missing or fails validation. */ export const requireSlugArg = ( args: Record, @@ -20,7 +38,7 @@ export const requireSlugArg = ( ): string => { const value = args[key]; if (!isValidSlug(value)) { - throw new QueryArgError( + throw new AnalysisArgError( `Argument "${key}" must be a slug matching ${SLUG_PATTERN.source}`, ); } diff --git a/apps/hash-api/src/auth/create-auth-handlers.ts b/apps/hash-api/src/auth/create-auth-handlers.ts index 3122687ee78..a9e7625c0f6 100644 --- a/apps/hash-api/src/auth/create-auth-handlers.ts +++ b/apps/hash-api/src/auth/create-auth-handlers.ts @@ -7,6 +7,7 @@ import { publicUserAccountId } from "@local/hash-backend-utils/public-user-accou import { createUser, getUser } from "../graph/knowledge/system-types/user"; import { systemAccountId } from "../graph/system-account"; +import { telemetry } from "../telemetry/telemetry"; import { hydraAdmin } from "./ory-hydra"; import { kratosFrontendApi } from "./ory-kratos"; @@ -67,11 +68,26 @@ const kratosAfterRegistrationHookHandler = throw new Error("User registration is disabled."); } - await createUser(context, authentication, { + const user = await createUser(context, authentication, { emails, kratosIdentityId, }); + // This is a Kratos -> server webhook, so there is no `req.user` and + // `req.ip` is Kratos's, not the registrant's. Emit via the actor path + // keyed on the newly created user's accountId. + const actor = { + accountId: user.accountId, + shortname: user.shortname, + }; + telemetry.identifyActor(actor, { + email: emails[0], + shortname: user.shortname, + }); + telemetry.trackForActor(actor, "user_register", { + email: emails[0], + }); + res.status(200).end(); } catch (error) { // The kratos hook can interrupt creation on 4xx and 5xx responses. diff --git a/apps/hash-api/src/email/create-email-transporter.ts b/apps/hash-api/src/email/create-email-transporter.ts index 18fde6d81ae..216b91bc192 100644 --- a/apps/hash-api/src/email/create-email-transporter.ts +++ b/apps/hash-api/src/email/create-email-transporter.ts @@ -6,7 +6,12 @@ import { monorepoRootDir, } from "@local/hash-backend-utils/environment"; -import { isDevEnv, isProdEnv, isTestEnv } from "../lib/env-config"; +import { + isDevEnv, + isProdEnv, + isStagingEnv, + isTestEnv, +} from "../lib/env-config"; import { logger } from "../logger"; import { AwsSesEmailTransporter, DummyEmailTransporter } from "./transporters"; import { SmtpEmailTransporter } from "./transporters/smtp-email-transporter"; @@ -33,7 +38,11 @@ export const createEmailTransporter = (): EmailTransporter => { }); } - const subjectPrefix = isProdEnv ? undefined : "[DEV SITE] "; + const subjectPrefix = isProdEnv + ? undefined + : isStagingEnv + ? "[STAGING SITE] " + : "[DEV SITE] "; if (transporterType === "aws") { return new AwsSesEmailTransporter({ diff --git a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts index 424f9c671ae..2ef01937d0b 100644 --- a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts +++ b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types.ts @@ -7,7 +7,7 @@ import { NotFoundError } from "@local/hash-backend-utils/error"; import { getHashInstance } from "@local/hash-backend-utils/hash-instance"; import { systemPropertyTypes } from "@local/hash-isomorphic-utils/ontology-type-ids"; -import { isProdEnv } from "../../lib/env-config"; +import { isDevEnv } from "../../lib/env-config"; import { systemAccountId } from "../system-account"; import type { ImpureGraphContext } from "../context-types"; @@ -137,7 +137,7 @@ export const migrateOntologyTypes = async (params: { * If the migration file is marked with `.dev.migration.ts`, it * should only be seeded in non-production environments. */ - if (isProdEnv && migrationFileName.endsWith(".dev.migration.ts")) { + if (!isDevEnv && migrationFileName.endsWith(".dev.migration.ts")) { params.logger.debug(`Skipping dev migration ${migrationFileName}`); continue; } diff --git a/apps/hash-api/src/index.ts b/apps/hash-api/src/index.ts index ae0a0fdcd92..e825765db47 100644 --- a/apps/hash-api/src/index.ts +++ b/apps/hash-api/src/index.ts @@ -47,6 +47,7 @@ import { gptQueryEntities } from "./ai/gpt/gpt-query-entities"; import { gptQueryTypes } from "./ai/gpt/gpt-query-types"; import { upsertGptOauthClient } from "./ai/gpt/upsert-gpt-oauth-client"; import { openInferEntitiesWebSocket } from "./ai/infer-entities-websocket"; +import { setupAnalysisHandler } from "./analysis/setup-analysis-handler"; import { addKratosAfterRegistrationHandler, createAuthMiddleware, @@ -86,13 +87,13 @@ import { port, } from "./lib/env-config"; import { logger } from "./logger"; -import { setupQueryHandler } from "./query"; import { seedOrgsAndUsers } from "./seed-data"; import { setupFileDownloadProxyHandler, setupStorageProviders, } from "./storage"; -import { setupTelemetry } from "./telemetry/snowplow-setup"; +import { telemetry } from "./telemetry/telemetry"; +import { setupTelemetryHandler } from "./telemetry/telemetry-endpoint"; import type { ProvidedEntityEditionProvenance } from "@blockprotocol/type-system"; import type { ErrorRequestHandler, Request, Response } from "express"; @@ -345,17 +346,6 @@ const kratosProxy = createProxyMiddleware({ const main = async () => { logger.info("Type System initialized"); - if (process.env.HASH_TELEMETRY_ENABLED === "true") { - logger.info("Starting [Snowplow] telemetry"); - - const snowplowTracker = await setupTelemetry(); - - shutdown.addCleanup("Snowplow Telemetry", async () => { - logger.info("Flushing [Snowplow] telemetry"); - await snowplowTracker.flush(); - }); - } - // Request ID generator const nanoid = customAlphabet( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", @@ -748,7 +738,10 @@ const main = async () => { setupFileDownloadProxyHandler(app, keyv); - setupQueryHandler(app, keyv); + setupAnalysisHandler(app, keyv); + + setupTelemetryHandler(app); + shutdown.addCleanup("Rudderstack Telemetry", async () => telemetry.flush()); setupBlockProtocolExternalServiceMethodProxy(app); diff --git a/apps/hash-api/src/instrument.mjs b/apps/hash-api/src/instrument.mjs index 9f48bdef97d..68d954b072c 100644 --- a/apps/hash-api/src/instrument.mjs +++ b/apps/hash-api/src/instrument.mjs @@ -13,7 +13,7 @@ import { registerOpenTelemetry, } from "@local/hash-backend-utils/opentelemetry"; -import { isProdEnv } from "./lib/env-config"; +import { isProdEnv, isStagingEnv } from "./lib/env-config"; /** * OpenTelemetry setup handle, exported so `index.ts` can wire @@ -55,7 +55,7 @@ export const otelSetup = (() => { // Outside production, fail loud: the only realistic causes here are // coding errors (bad URL, malformed instrumentation config) and // hiding them in dev/CI loses regressions. - if (!isProdEnv) { + if (!isProdEnv && !isStagingEnv) { throw error; } // eslint-disable-next-line no-console diff --git a/apps/hash-api/src/lib/env-config.ts b/apps/hash-api/src/lib/env-config.ts index c36e203601a..21323a0288d 100644 --- a/apps/hash-api/src/lib/env-config.ts +++ b/apps/hash-api/src/lib/env-config.ts @@ -10,7 +10,9 @@ export const isDevEnv = process.env.NODE_ENV === "development" || !process.env.NODE_ENV; /** Whether the backend is running in the production environment. */ -export const isProdEnv = process.env.NODE_ENV === "production"; +export const isProdEnv = process.env.ENVIRONMENT === "production"; + +export const isStagingEnv = process.env.ENVIRONMENT === "staging"; /** The port the backend server should be running on */ export const port = PORT ? parseInt(PORT, 10) : 5001; diff --git a/apps/hash-api/src/query.ts b/apps/hash-api/src/query.ts deleted file mode 100644 index 4e0cbb314fb..00000000000 --- a/apps/hash-api/src/query.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { supplyChainQueries } from "./query/queries/supply-chain"; -import { resolveInvocation } from "./query/resolve-query"; -import { registerQueries } from "./query/shared/query-registry"; - -import type { - QueryRequest, - QueryResponse, -} from "@local/hash-isomorphic-utils/query/types"; -import type { Express } from "express"; -import type Keyv from "keyv"; - -/** Upper bound on invocations per batch request, to bound work per call. */ -const MAX_BATCH_SIZE = 25; - -let queriesRegistered = false; - -/** - * Register the built-in named queries. Idempotent so repeated setup calls (e.g. - * across test harness reinitialisation) don't throw on duplicate registration. - */ -const ensureQueriesRegistered = () => { - if (queriesRegistered) { - return; - } - registerQueries(supplyChainQueries); - queriesRegistered = true; -}; - -/** - * Mounts the generic query gateway at `POST /api/query`. - * - * The gateway is a thin control plane: it authenticates the caller, authorises - * each invocation against its scoped web(s), resolves named queries to stored - * artifacts, and returns short-lived URLs the client fetches directly from - * storage (the data plane). Artifact bytes never pass through the API. - */ -export const setupQueryHandler = (app: Express, cache: Keyv) => { - ensureQueriesRegistered(); - - app.post("/api/query", async (req, res) => { - const { user } = req; - if (!user) { - res.status(401).json({ error: "Authentication required" }); - return; - } - - const body = req.body as QueryRequest | undefined; - if (!body || !Array.isArray(body.requests)) { - res - .status(400) - .json({ - error: "Request body must be { requests: QueryInvocation[] }", - }); - return; - } - - if (body.requests.length > MAX_BATCH_SIZE) { - res - .status(400) - .json({ error: `Too many requests (max ${MAX_BATCH_SIZE})` }); - return; - } - - const { graphApi, uploadProvider } = req.context; - - const results = await Promise.all( - body.requests.map((invocation) => - resolveInvocation({ - invocation, - actorId: user.accountId, - graphApi, - uploadProvider, - cache, - }), - ), - ); - - res.json({ results } satisfies QueryResponse); - }); -}; diff --git a/apps/hash-api/src/query/resolve-query.ts b/apps/hash-api/src/query/resolve-query.ts deleted file mode 100644 index b28a7c6529b..00000000000 --- a/apps/hash-api/src/query/resolve-query.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { getActorGroupRole } from "@local/hash-graph-sdk/principal/actor-group"; - -import { logger } from "../logger"; -import { - DatasetUnavailableError, - QueryArgError, - QueryNotFoundError, -} from "./shared/errors"; -import { getQuery } from "./shared/query-registry"; - -import type { GraphApi } from "../graph/context-types"; -import type { ActorEntityUuid } from "@blockprotocol/type-system"; -import type { FileStorageProvider } from "@local/hash-backend-utils/file-storage"; -import type { - QueryInvocation, - QueryResult, -} from "@local/hash-isomorphic-utils/query/types"; -import type Keyv from "keyv"; - -/** - * Presigned URLs are short-lived: the frontend re-queries the gateway when a - * URL nears expiry rather than holding long-lived credentials. We cache the - * URL (minus an offset) so repeat queries within the window are cheap. - */ -const QUERY_URL_EXPIRATION_SECONDS = 60 * 60; -const QUERY_URL_CACHE_OFFSET_SECONDS = 60 * 5; - -/** Internal sentinel for an authorisation failure on a specific web. */ -class WebAuthorisationError extends Error {} - -export interface ResolveInvocationParams { - invocation: QueryInvocation; - actorId: ActorEntityUuid; - graphApi: GraphApi; - uploadProvider: FileStorageProvider; - cache: Keyv; -} - -export const resolveInvocation = async ({ - invocation, - actorId, - graphApi, - uploadProvider, - cache, -}: ResolveInvocationParams): Promise => { - const id = typeof invocation.id === "string" ? invocation.id : ""; - const queryName = invocation.query; - const webIds = invocation.webIds; - const args = invocation.args ?? {}; - - const asResult = (partial: Omit): QueryResult => ({ - id, - ...partial, - }); - - if (typeof queryName !== "string" || queryName.length === 0) { - return asResult({ status: "error", error: "Missing query name" }); - } - - const query = getQuery(queryName); - if (!query) { - return asResult({ status: "error", error: `Unknown query "${queryName}"` }); - } - - if (!Array.isArray(webIds) || webIds.length === 0) { - return asResult({ - status: "error", - error: "At least one webId is required", - }); - } - - const requiredRole = query.requiredWebRole ?? "member"; - - try { - // Authorise the actor against every web the invocation is scoped to. - for (const webId of webIds) { - const role = await getActorGroupRole( - graphApi, - { actorId }, - { actorId, actorGroupId: webId }, - ); - - if (!role) { - throw new WebAuthorisationError( - `You do not have access to web ${webId}`, - ); - } - if (requiredRole === "administrator" && role !== "administrator") { - throw new WebAuthorisationError( - `Administrator role required in web ${webId}`, - ); - } - } - - const loadArtifact = async (key: string): Promise => { - try { - return await uploadProvider.downloadDirect({ key }); - } catch { - return null; - } - }; - - const resolution = await query.resolve({ - webId: webIds[0]!, - webIds, - args, - loadArtifact, - }); - - if (resolution.status === "computing") { - return asResult({ - status: "computing", - retryAfterMs: resolution.retryAfterMs ?? 1000, - }); - } - - const artifacts = await Promise.all( - (resolution.artifacts ?? []).map(async (ref) => { - const cacheKey = `query-presign:${ref.key}`; - let url = await cache.get(cacheKey); - - if (!url) { - url = await uploadProvider.presignDownloadByKey({ - key: ref.key, - expiresInSeconds: QUERY_URL_EXPIRATION_SECONDS, - }); - - try { - await cache.set( - cacheKey, - url, - (QUERY_URL_EXPIRATION_SECONDS - QUERY_URL_CACHE_OFFSET_SECONDS) * - 1000, - ); - } catch (error) { - logger.warn( - `Could not cache presigned query URL [key=${ref.key}]: ${error}`, - ); - } - } - - return { - name: ref.name, - format: ref.format ?? "json", - url, - expiresAt: new Date( - Date.now() + QUERY_URL_EXPIRATION_SECONDS * 1000, - ).toISOString(), - }; - }), - ); - - return asResult({ status: "ready", artifacts }); - } catch (error) { - if ( - error instanceof WebAuthorisationError || - error instanceof QueryArgError || - error instanceof QueryNotFoundError || - error instanceof DatasetUnavailableError - ) { - return asResult({ status: "error", error: error.message }); - } - - logger.error( - `Unexpected error resolving query "${queryName}": ${ - error instanceof Error ? error.stack : String(error) - }`, - ); - return asResult({ status: "error", error: "Internal error" }); - } -}; diff --git a/apps/hash-api/src/query/shared/query-registry.ts b/apps/hash-api/src/query/shared/query-registry.ts deleted file mode 100644 index ee4c1379a07..00000000000 --- a/apps/hash-api/src/query/shared/query-registry.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { RoleName, WebId } from "@blockprotocol/type-system"; - -/** - * Reference to a stored artifact that a named query resolves to. The gateway - * turns each into a short-lived, directly-fetchable URL. - */ -export interface ArtifactKeyRef { - /** Logical name within the query result, e.g. `"graph"`. */ - name: string; - /** Storage key, relative to the provider's default location. */ - key: string; - /** Wire format hint surfaced to the client (defaults to `"json"`). */ - format?: string; -} - -/** Context handed to a named query when resolving an invocation. */ -export interface QueryResolutionContext { - /** - * The primary web the query is scoped to. For single-web queries this is the - * (already authorised) web the artifacts live under. - */ - webId: WebId; - /** All authorised webs from the invocation (for future cross-web queries). */ - webIds: WebId[]; - /** Validated-as-an-object query arguments (may be empty). */ - args: Record; - /** - * Read a stored artifact's raw bytes by key, e.g. to load a dataset pointer - * or manifest during resolution. Returns `null` if the object is missing. - */ - loadArtifact: (key: string) => Promise; -} - -/** The outcome of resolving a single invocation. */ -export interface QueryResolution { - status: "ready" | "computing"; - /** Present when `status === "ready"`. */ - artifacts?: ArtifactKeyRef[]; - /** Present when `status === "computing"`: client poll hint. */ - retryAfterMs?: number; -} - -/** - * A server-registered query. Each query owns its own argument validation and - * (where relevant) dataset/manifest membership checks, keeping the gateway and - * registry domain-agnostic. - */ -export interface NamedQuery { - /** Unique name clients reference, e.g. `"productGraph"`. */ - name: string; - /** - * Minimum role the actor must hold in each scoped web. Defaults to `"member"` - * (any web role grants access). - */ - requiredWebRole?: RoleName; - resolve: (ctx: QueryResolutionContext) => Promise; -} - -const registry = new Map(); - -/** Register a named query. Throws if the name is already taken. */ -export const registerQuery = (query: NamedQuery): void => { - if (registry.has(query.name)) { - throw new Error(`Query "${query.name}" is already registered`); - } - registry.set(query.name, query); -}; - -export const registerQueries = (queries: readonly NamedQuery[]): void => { - for (const query of queries) { - registerQuery(query); - } -}; - -export const getQuery = (name: string): NamedQuery | undefined => - registry.get(name); - -/** Exposed for tests: clear all registered queries. */ -export const clearQueryRegistry = (): void => { - registry.clear(); -}; diff --git a/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts b/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts index 7b02cde48fa..bb7f503f81f 100644 --- a/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts +++ b/apps/hash-api/src/seed-data/seed-supply-chain-demo.ts @@ -2,6 +2,7 @@ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { webScopedKey } from "../analysis/shared/storage-key"; import { getOrgByShortname } from "../graph/knowledge/system-types/org"; import { systemAccountId } from "../graph/system-account"; @@ -9,7 +10,7 @@ import type { ImpureGraphContext } from "../graph/context-types"; import type { Logger } from "@local/hash-backend-utils/logger"; /** - * Vendored, web-agnostic demo dataset for the supply-chain (value-chain-timing) views. + * Vendored, web-agnostic demo dataset for the supply-chain views. */ const DEMO_DATA_DIR = path.join( path.dirname(fileURLToPath(import.meta.url)), @@ -50,7 +51,7 @@ const readVendoredDatasetVersion = (): string | null => { /** * Upload the vendored supply-chain demo dataset into the `@example-org` web's - * storage namespace so the query gateway can serve it to seeded users. + * storage namespace so the analysis gateway can serve it to seeded users. * * Safe to call on every boot: * - no-ops in environments without the example org (e.g. production) or without @@ -92,7 +93,7 @@ export const seedSupplyChainDemo = async (params: { } const { webId } = org; - const currentKey = `${STORAGE_NAMESPACE}/${webId}/current.json`; + const currentKey = webScopedKey(webId, STORAGE_NAMESPACE, "current.json"); const vendoredVersion = readVendoredDatasetVersion(); // Idempotency: if this web already has the vendored version seeded, skip the @@ -122,7 +123,7 @@ export const seedSupplyChainDemo = async (params: { .relative(DEMO_DATA_DIR, absPath) .split(path.sep) .join("/"); - const key = `${STORAGE_NAMESPACE}/${webId}/${relKey}`; + const key = webScopedKey(webId, STORAGE_NAMESPACE, relKey); const body = await fs.promises.readFile(absPath); await uploadProvider.uploadDirect({ diff --git a/apps/hash-api/src/telemetry/environment.test.ts b/apps/hash-api/src/telemetry/environment.test.ts new file mode 100644 index 00000000000..0bcf68ff60b --- /dev/null +++ b/apps/hash-api/src/telemetry/environment.test.ts @@ -0,0 +1,33 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +const loadTelemetryEnvironment = async () => { + vi.resetModules(); + const module = await import("./environment"); + return module.telemetryEnvironment; +}; + +describe("telemetryEnvironment", () => { + afterEach(() => { + vi.unstubAllEnvs(); + }); + + it("defaults to development when ENVIRONMENT is unset", async () => { + vi.stubEnv("ENVIRONMENT", ""); + await expect(loadTelemetryEnvironment()).resolves.toBe("development"); + }); + + it("resolves production from ENVIRONMENT", async () => { + vi.stubEnv("ENVIRONMENT", "production"); + await expect(loadTelemetryEnvironment()).resolves.toBe("production"); + }); + + it("resolves staging from ENVIRONMENT", async () => { + vi.stubEnv("ENVIRONMENT", "staging"); + await expect(loadTelemetryEnvironment()).resolves.toBe("staging"); + }); + + it("treats any other ENVIRONMENT value as development", async () => { + vi.stubEnv("ENVIRONMENT", "qa"); + await expect(loadTelemetryEnvironment()).resolves.toBe("development"); + }); +}); diff --git a/apps/hash-api/src/telemetry/environment.ts b/apps/hash-api/src/telemetry/environment.ts new file mode 100644 index 00000000000..e148ae9cc1c --- /dev/null +++ b/apps/hash-api/src/telemetry/environment.ts @@ -0,0 +1,9 @@ +import { isProdEnv, isStagingEnv } from "../lib/env-config"; + +import type { TelemetryEnvironment } from "@local/hash-isomorphic-utils/telemetry/types"; + +export const telemetryEnvironment: TelemetryEnvironment = isProdEnv + ? "production" + : isStagingEnv + ? "staging" + : "development"; diff --git a/apps/hash-api/src/telemetry/rudderstack.ts b/apps/hash-api/src/telemetry/rudderstack.ts deleted file mode 100644 index 363c788fa8f..00000000000 --- a/apps/hash-api/src/telemetry/rudderstack.ts +++ /dev/null @@ -1,40 +0,0 @@ -import RudderAnalytics from "@rudderstack/rudder-sdk-node"; - -import { frontendDomain } from "@local/hash-isomorphic-utils/environment"; - -const RUDDERSTACK_KEY = - process.env.HASH_API_RUDDERSTACK_KEY || "2SKw8Q5jz5g08LNKpk0Ag82N7HL"; - -export class Telemetry { - private static rudder_client: RudderAnalytics | undefined | null = undefined; - - private static client(): RudderAnalytics | null { - if (Telemetry.rudder_client === undefined) { - if (frontendDomain === "localhost") { - Telemetry.rudder_client = null; - return null; - } - Telemetry.rudder_client = new RudderAnalytics(RUDDERSTACK_KEY, { - dataPlaneUrl: "https://hashdjsn.dataplane.rudderstack.com", - }); - } - return Telemetry.rudder_client; - } - - public static userRegister(params: { - shortname: string; - displayName: string; - email: string; - }): void { - Telemetry.client()?.track({ - userId: params.email, - event: "user_register", - properties: { - domain: frontendDomain, - name: params.displayName, - shortname: params.shortname, - email: params.email, - }, - }); - } -} diff --git a/apps/hash-api/src/telemetry/snowplow-setup.ts b/apps/hash-api/src/telemetry/snowplow-setup.ts deleted file mode 100644 index f1777ae1474..00000000000 --- a/apps/hash-api/src/telemetry/snowplow-setup.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - buildStructEvent, - newTracker, - type Tracker, -} from "@snowplow/node-tracker"; - -import { getRequiredEnv } from "@local/hash-backend-utils/environment"; - -/** - * Sets up snowplow telemetry for HASH usage. Disabled by default. - * This tracking function simply sends an event when the platform starts to record usage metrics. - */ -export const setupTelemetry = async (): Promise => { - const protocol = - process.env.HASH_TELEMETRY_HTTPS === "true" ? "https" : "http"; - - const tracker = newTracker( - { - namespace: "usageTracker", - appId: getRequiredEnv("HASH_TELEMETRY_APP_ID"), - encodeBase64: true, - }, - { - endpoint: getRequiredEnv("HASH_TELEMETRY_DESTINATION"), - protocol, - }, - ); - - // This `srv` value means it's for server-side tracking (see https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/snowplow-tracker-protocol/) - tracker.setPlatform("srv"); - - // We track an event to record usage of the platform - tracker.track( - buildStructEvent({ - category: "usage", - action: "start-platform", - }), - ); - - await tracker.flush(); - - return tracker; -}; diff --git a/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts b/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts new file mode 100644 index 00000000000..8567a484074 --- /dev/null +++ b/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts @@ -0,0 +1,61 @@ +import { describe, expect, it } from "vitest"; + +import { parseTelemetryEvent } from "./telemetry-endpoint"; + +describe("parseTelemetryEvent", () => { + it("accepts a page event with a name", () => { + expect(parseTelemetryEvent({ type: "page", name: "/foo" })).toEqual({ + type: "page", + name: "/foo", + properties: undefined, + }); + }); + + it("accepts an allowlisted track event", () => { + expect( + parseTelemetryEvent({ + type: "track", + name: "supply_chain_product_viewed", + properties: { productId: "abc" }, + }), + ).toEqual({ + type: "track", + name: "supply_chain_product_viewed", + properties: { productId: "abc" }, + }); + }); + + it("rejects a non-allowlisted track event name", () => { + expect( + parseTelemetryEvent({ type: "track", name: "analysis_run" }), + ).toBeNull(); + expect( + parseTelemetryEvent({ type: "track", name: "arbitrary_event" }), + ).toBeNull(); + }); + + it("rejects unknown event types", () => { + expect(parseTelemetryEvent({ type: "identify", name: "x" })).toBeNull(); + }); + + it("rejects a page event without a name", () => { + expect(parseTelemetryEvent({ type: "page" })).toBeNull(); + expect(parseTelemetryEvent({ type: "page", name: "" })).toBeNull(); + }); + + it("rejects non-objects", () => { + expect(parseTelemetryEvent(null)).toBeNull(); + expect(parseTelemetryEvent("page")).toBeNull(); + expect(parseTelemetryEvent(42)).toBeNull(); + }); + + it("drops non-object properties rather than forwarding them", () => { + expect( + parseTelemetryEvent({ + type: "page", + name: "/foo", + properties: ["not", "an", "object"], + }), + ).toEqual({ type: "page", name: "/foo", properties: undefined }); + }); +}); diff --git a/apps/hash-api/src/telemetry/telemetry-endpoint.ts b/apps/hash-api/src/telemetry/telemetry-endpoint.ts new file mode 100644 index 00000000000..e1c48a16461 --- /dev/null +++ b/apps/hash-api/src/telemetry/telemetry-endpoint.ts @@ -0,0 +1,112 @@ +import { ipKeyGenerator, rateLimit } from "express-rate-limit"; + +import { frontendTrackEventNames } from "@local/hash-isomorphic-utils/telemetry/types"; + +import { telemetry } from "./telemetry"; + +import type { + FrontendTelemetryEvent, + FrontendTrackEventName, + TelemetryRequest, +} from "@local/hash-isomorphic-utils/telemetry/types"; +import type { Express, Request } from "express"; + +/** Upper bound on events accepted per request, to bound work per call. */ +const MAX_EVENTS_PER_BATCH = 10; + +const allowedTrackEvents = new Set(frontendTrackEventNames); + +/** + * Per-IP rate limiter for the telemetry gateway. Anonymous callers are allowed + * (page views happen before login) but throttled harder than authenticated + * ones, since they are unauthenticated and cheap to spoof. + */ +const telemetryRateLimiter = rateLimit({ + windowMs: process.env.NODE_ENV === "test" ? 10 : 1000 * 60, // 1 minute + limit: (req) => (req.user ? 240 : 30), + standardHeaders: true, + legacyHeaders: false, + keyGenerator: (req) => (req.ip ? ipKeyGenerator(req.ip) : "ip-unavailable"), +}); + +/** + * Validate and narrow a single client-provided event. Returns `null` for any + * event that is malformed or names a non-allowlisted track event, so the + * browser can never inject arbitrary or server-only event names. + * + * Exported for unit testing. + */ +export const parseTelemetryEvent = ( + value: unknown, +): FrontendTelemetryEvent | null => { + if (typeof value !== "object" || value === null) { + return null; + } + const candidate = value as Record; + const properties = + typeof candidate.properties === "object" && + candidate.properties !== null && + !Array.isArray(candidate.properties) + ? (candidate.properties as Record) + : undefined; + + if (candidate.type === "page") { + if (typeof candidate.name !== "string" || candidate.name.length === 0) { + return null; + } + return { type: "page", name: candidate.name, properties }; + } + + if (candidate.type === "track") { + if ( + typeof candidate.name !== "string" || + !allowedTrackEvents.has(candidate.name) + ) { + return null; + } + return { + type: "track", + name: candidate.name as FrontendTrackEventName, + properties, + }; + } + + return null; +}; + +/** + * Mounts the telemetry gateway at `POST /api/telemetry`. + * + * The browser reports allowlisted events here; the server stamps all trusted + * fields (identity, IP, environment) and forwards to Rudderstack, flagging + * everything as `frontendProvided`. Client-supplied identity/IP/environment are + * never trusted. + */ +export const setupTelemetryHandler = (app: Express) => { + app.post("/api/telemetry", telemetryRateLimiter, (req: Request, res) => { + const body = req.body as Partial | undefined; + + if (!body || !Array.isArray(body.events)) { + res.status(400).json({ error: "Request body must be { events: [...] }" }); + return; + } + + if (body.events.length > MAX_EVENTS_PER_BATCH) { + res + .status(400) + .json({ error: `Too many events (max ${MAX_EVENTS_PER_BATCH})` }); + return; + } + + const events = body.events + .map(parseTelemetryEvent) + .filter((event): event is FrontendTelemetryEvent => event !== null); + + const anonymousId = + typeof body.anonymousId === "string" ? body.anonymousId : undefined; + + telemetry.trackFromClient(req, { anonymousId, events }); + + res.status(204).end(); + }); +}; diff --git a/apps/hash-api/src/telemetry/telemetry.ts b/apps/hash-api/src/telemetry/telemetry.ts new file mode 100644 index 00000000000..1a5fd130daa --- /dev/null +++ b/apps/hash-api/src/telemetry/telemetry.ts @@ -0,0 +1,214 @@ +import RudderAnalytics from "@rudderstack/rudder-sdk-node"; + +import { frontendDomain } from "@local/hash-isomorphic-utils/environment"; + +import { logger } from "../logger"; +import { telemetryEnvironment } from "./environment"; + +import type { + FrontendTelemetryEvent, + TelemetryEnvironment, +} from "@local/hash-isomorphic-utils/telemetry/types"; +import type { Request } from "express"; + +const RUDDERSTACK_KEY = process.env.HASH_API_RUDDERSTACK_KEY; +const RUDDERSTACK_DATA_PLANE_URL = + process.env.HASH_API_RUDDERSTACK_DATA_PLANE_URL; + +/** Server-only event names */ +export type ServerTelemetryEventName = "analysis_run" | "user_register"; + +/** An actor identity for req-less callers (background jobs, webhooks). */ +export interface TelemetryActor { + accountId: string; + shortname?: string; +} + +/** + * The common envelope every event shares. Built internally by the service from + * a `req` or an actor; callers never construct one themselves. + */ +interface EventEnvelope { + userId?: string; + anonymousId?: string; + context: { + ip?: string; + userAgent?: string; + app: { environment: TelemetryEnvironment; frontendDomain: string }; + }; + baseProperties: { + environment: TelemetryEnvironment; + frontendDomain: string; + shortname?: string; + frontendProvided: boolean; + }; + timestamp: Date; +} + +class TelemetryService { + private client: RudderAnalytics | null | undefined = undefined; + + private getClient(): RudderAnalytics | null { + if (this.client === undefined) { + if (!RUDDERSTACK_KEY || !RUDDERSTACK_DATA_PLANE_URL) { + this.client = null; + return null; + } + this.client = new RudderAnalytics(RUDDERSTACK_KEY, { + dataPlaneUrl: RUDDERSTACK_DATA_PLANE_URL, + }); + } + return this.client; + } + + /** The single place a request-scoped envelope is built. */ + private buildEnvelope( + req: Request, + opts: { frontendProvided: boolean; anonymousId?: string }, + ): EventEnvelope { + const { user } = req; + return { + userId: user?.accountId, + anonymousId: user ? undefined : opts.anonymousId, + context: { + ip: req.ip, + userAgent: req.headers["user-agent"], + app: { environment: telemetryEnvironment, frontendDomain }, + }, + baseProperties: { + environment: telemetryEnvironment, + frontendDomain, + shortname: user?.shortname, + frontendProvided: opts.frontendProvided, + }, + timestamp: new Date(), + }; + } + + /** Envelope for req-less callers: no IP/user-agent, never frontend-provided. */ + private buildActorEnvelope(actor: TelemetryActor): EventEnvelope { + return { + userId: actor.accountId, + context: { + app: { environment: telemetryEnvironment, frontendDomain }, + }, + baseProperties: { + environment: telemetryEnvironment, + frontendDomain, + shortname: actor.shortname, + frontendProvided: false, + }, + timestamp: new Date(), + }; + } + + private emit( + envelope: EventEnvelope, + event: string, + properties: Record, + ): void { + const client = this.getClient(); + // The SDK requires an identity; drop anonymous-and-unidentified events. + if (!client || (!envelope.userId && !envelope.anonymousId)) { + return; + } + // The SDK's `apiObject` type does not accept `unknown`-valued property bags, + // so we cast at this boundary rather than constraining dynamic properties. + client.track({ + userId: envelope.userId, + anonymousId: envelope.anonymousId, + event, + properties: { ...envelope.baseProperties, ...properties }, + context: envelope.context, + timestamp: envelope.timestamp, + } as unknown as RudderAnalytics.TrackParams); + } + + private emitPage( + envelope: EventEnvelope, + name: string, + properties: Record, + ): void { + const client = this.getClient(); + if (!client || (!envelope.userId && !envelope.anonymousId)) { + return; + } + client.page({ + userId: envelope.userId, + anonymousId: envelope.anonymousId, + name, + properties: { ...envelope.baseProperties, ...properties }, + context: envelope.context, + timestamp: envelope.timestamp, + } as unknown as RudderAnalytics.PageParams); + } + + // ─── Public, envelope-free API ─── + + /** A server-origin event tied to an incoming request. */ + track( + req: Request, + event: ServerTelemetryEventName, + properties: Record = {}, + ): void { + this.emit( + this.buildEnvelope(req, { frontendProvided: false }), + event, + properties, + ); + } + + /** A server-origin event for a req-less caller (webhooks, background jobs). */ + trackForActor( + actor: TelemetryActor, + event: ServerTelemetryEventName, + properties: Record = {}, + ): void { + this.emit(this.buildActorEnvelope(actor), event, properties); + } + + /** Relay allowlisted events reported by the browser. */ + trackFromClient( + req: Request, + payload: { anonymousId?: string; events: FrontendTelemetryEvent[] }, + ): void { + const envelope = this.buildEnvelope(req, { + frontendProvided: true, + anonymousId: payload.anonymousId, + }); + + for (const ev of payload.events) { + if (ev.type === "page") { + this.emitPage(envelope, ev.name, ev.properties ?? {}); + } else { + this.emit(envelope, ev.name, ev.properties ?? {}); + } + } + } + + /** Associate an actor with traits (e.g. on registration). */ + identifyActor(actor: TelemetryActor, traits: Record): void { + const client = this.getClient(); + if (!client) { + return; + } + client.identify({ + userId: actor.accountId, + traits, + context: { + app: { environment: telemetryEnvironment, frontendDomain }, + }, + } as unknown as RudderAnalytics.IdentifyParams); + } + + /** Flush buffered events; call on graceful shutdown. */ + async flush(): Promise { + try { + await this.client?.flush(); + } catch (error) { + logger.warn(`Could not flush telemetry client: ${error}`); + } + } +} + +export const telemetry = new TelemetryService(); diff --git a/apps/hash-frontend/src/lib/supply-chain/query-client.ts b/apps/hash-frontend/src/lib/supply-chain/query-client.ts deleted file mode 100644 index ee7511d948f..00000000000 --- a/apps/hash-frontend/src/lib/supply-chain/query-client.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { apiOrigin } from "@local/hash-isomorphic-utils/environment"; - -import type { - ArtifactRef, - QueryInvocation, - QueryResponse, - QueryResult, -} from "@local/hash-isomorphic-utils/query/types"; - -/** - * Client for the generic query gateway (`POST /api/query`). The gateway returns - * short-lived URLs; artifact bytes are fetched directly from storage (the data - * plane) rather than proxied through the API. - */ - -export class QueryError extends Error { - constructor(message: string) { - super(message); - this.name = "QueryError"; - } -} - -/** POST a batch of named-query invocations and return their results. */ -export const runQueries = async ( - requests: QueryInvocation[], -): Promise => { - const response = await fetch(`${apiOrigin}/api/query`, { - method: "POST", - credentials: "include", - headers: { "content-type": "application/json" }, - body: JSON.stringify({ requests }), - }); - - if (!response.ok) { - throw new QueryError(`Query request failed with status ${response.status}`); - } - - const body = (await response.json()) as QueryResponse; - return body.results; -}; - -/** Fetch and JSON-parse the bytes referenced by a resolved artifact. */ -export const fetchArtifactJson = async (ref: ArtifactRef): Promise => { - // Presigned (S3) URLs carry auth in the query string and must NOT receive - // cookies; same-origin (local dev) URLs go through the API and need them. - const sameOrigin = ref.url.startsWith(apiOrigin); - const response = await fetch(ref.url, { - credentials: sameOrigin ? "include" : "omit", - }); - - if (!response.ok) { - throw new QueryError( - `Artifact "${ref.name}" fetch failed with status ${response.status}`, - ); - } - - return (await response.json()) as T; -}; - -const resultReady = (result: QueryResult | undefined): QueryResult => { - if (!result) { - throw new QueryError("Empty query response"); - } - if (result.status === "error") { - throw new QueryError(result.error ?? "Query returned an error"); - } - if (result.status !== "ready" || !result.artifacts?.length) { - throw new QueryError(`Query result not ready (status: ${result.status})`); - } - return result; -}; - -/** - * Run a single named query and return the parsed JSON of one of its artifacts - * (the primary/first by default, or the named one via `opts.artifact`). - */ -export const fetchQueryArtifact = async ( - invocation: Omit, - opts?: { artifact?: string }, -): Promise => { - const [result] = await runQueries([{ id: "q0", ...invocation }]); - const ready = resultReady(result); - - const ref = opts?.artifact - ? ready.artifacts!.find((a) => a.name === opts.artifact) - : ready.artifacts![0]; - - if (!ref) { - throw new QueryError( - `Artifact "${opts?.artifact ?? "(primary)"}" not present in result`, - ); - } - - return fetchArtifactJson(ref); -}; - -/** Like {@link fetchQueryArtifact} but resolves multiple named artifacts at once. */ -export const fetchQueryArtifacts = async ( - invocation: Omit, -): Promise> => { - const [result] = await runQueries([{ id: "q0", ...invocation }]); - const ready = resultReady(result); - return Object.fromEntries(ready.artifacts!.map((ref) => [ref.name, ref])); -}; diff --git a/apps/hash-frontend/src/pages/_app.page.tsx b/apps/hash-frontend/src/pages/_app.page.tsx index 86623505ad2..90c8fc01d18 100644 --- a/apps/hash-frontend/src/pages/_app.page.tsx +++ b/apps/hash-frontend/src/pages/_app.page.tsx @@ -36,6 +36,7 @@ import { SidebarContextProvider } from "../shared/layout/layout-with-sidebar/sid import { NotificationCountContextProvider } from "../shared/notification-count-context"; import { PropertyTypesContextProvider } from "../shared/property-types-context"; import { RoutePageInfoProvider } from "../shared/routing"; +import { trackPageView } from "../shared/telemetry-client"; import { ErrorFallback } from "./_app.page/error-fallback"; import { reportIframeReactError } from "./processes/shared/iframe-error-reporter"; import { redirectInGetInitialProps } from "./shared/_app.util"; @@ -142,6 +143,26 @@ const App: FunctionComponent = ({ setSentryUser({ authenticatedUser }); }, [authenticatedUser]); + useEffect(() => { + if (!router.isReady) { + return undefined; + } + + // Initial view (fires once the router is ready); subsequent views come from + // `routeChangeComplete`. `router.asPath` is intentionally omitted from the + // deps so we don't double-count navigations. + trackPageView(router.asPath); + + const handleRouteChange = (url: string) => { + trackPageView(url); + }; + router.events.on("routeChangeComplete", handleRouteChange); + return () => { + router.events.off("routeChangeComplete", handleRouteChange); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [router.isReady, router.events]); + // App UI often depends on [shortname] and other query params. However, // router.query is empty during server-side rendering for pages that don’t use // getServerSideProps. By showing app skeleton on the server, we avoid UI diff --git a/apps/hash-frontend/src/pages/supply-chain/index.page.tsx b/apps/hash-frontend/src/pages/supply-chain.page.tsx similarity index 69% rename from apps/hash-frontend/src/pages/supply-chain/index.page.tsx rename to apps/hash-frontend/src/pages/supply-chain.page.tsx index 2a6b31ff6a1..fbdbdf4e716 100644 --- a/apps/hash-frontend/src/pages/supply-chain/index.page.tsx +++ b/apps/hash-frontend/src/pages/supply-chain.page.tsx @@ -1,10 +1,10 @@ import { useRouter } from "next/router"; import { useEffect } from "react"; -import { useRegistry } from "../../vct/supply-chain/shared/registry-context"; -import { getSupplyChainLayout } from "./shared/supply-chain-layout"; +import { useRegistry } from "./supply-chain.page/shared/registry-contextry-context"; +import { getSupplyChainLayout } from "./supply-chain.page/shared/supply-chain-layoutupply-chain-layout"; -import type { NextPageWithLayout } from "../../shared/layout"; +import type { NextPageWithLayout } from "../shared/layout"; /** Supply-chain landing: send to the first product. */ const SupplyChainIndexPage: NextPageWithLayout = () => { diff --git a/apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain.page/product/[product-id].page.tsx similarity index 100% rename from apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx rename to apps/hash-frontend/src/pages/supply-chain.page/product/[product-id].page.tsx diff --git a/apps/hash-frontend/src/lib/supply-chain/data.ts b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts similarity index 73% rename from apps/hash-frontend/src/lib/supply-chain/data.ts rename to apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts index 875e88847c4..1a74e2481e8 100644 --- a/apps/hash-frontend/src/lib/supply-chain/data.ts +++ b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts @@ -1,16 +1,16 @@ import { + fetchAnalysisArtifact, + fetchAnalysisArtifacts, fetchArtifactJson, - fetchQueryArtifact, - fetchQueryArtifacts, -} from "./query-client"; +} from "../../../shared/analysis-client"; import type { WebId } from "@blockprotocol/type-system"; /** * Data-access layer for the supply-chain (value-chain-timing) views, ported * from the standalone SPA's `shared/data.ts`. Where the SPA fetched static JSON - * from `/data/...`, these go through the auth-gated query gateway, scoped to a - * `webId`. View-layer payload types (graph, step detail, site summary) are + * from `/data/...`, these go through the auth-gated analysis gateway, scoped to + * a `webId`. View-layer payload types (graph, step detail, site summary) are * supplied by the caller as type parameters during the component migration. */ @@ -28,25 +28,25 @@ export interface SiteRef { } export const fetchProducts = (webId: WebId): Promise => - fetchQueryArtifact({ - query: "listProducts", - webIds: [webId], + fetchAnalysisArtifact({ + analysis: "listProducts", + webId, }); export const fetchSites = (webId: WebId): Promise => - fetchQueryArtifact({ - query: "listSites", - webIds: [webId], + fetchAnalysisArtifact({ + analysis: "listSites", + webId, }).catch(() => []); export const fetchGraph = ( webId: WebId, productId: string, ): Promise => - fetchQueryArtifact({ - query: "productGraph", + fetchAnalysisArtifact({ + analysis: "productGraph", args: { productId }, - webIds: [webId], + webId, }); export const fetchStepDetail = ( @@ -54,10 +54,10 @@ export const fetchStepDetail = ( productId: string, stepId: string, ): Promise => - fetchQueryArtifact({ - query: "stepDetail", + fetchAnalysisArtifact({ + analysis: "stepDetail", args: { productId, stepId }, - webIds: [webId], + webId, }); export const fetchSiteSummary = async ( @@ -65,10 +65,10 @@ export const fetchSiteSummary = async ( siteId: string, ): Promise => { try { - return await fetchQueryArtifact({ - query: "siteSummary", + return await fetchAnalysisArtifact({ + analysis: "siteSummary", args: { siteId }, - webIds: [webId], + webId, }); } catch { return null; @@ -76,7 +76,7 @@ export const fetchSiteSummary = async ( }; /** - * Site-wide supplier performance. The query resolves two artifacts – + * Site-wide supplier performance. The analysis resolves two artifacts – * `performance` (aggregates) and `lines` (raw schedule lines for client-side * time-window recompute). We re-attach `lines` onto the performance payload to * match the SPA's `SiteSupplierPerformance` shape. Missing lines are tolerated. @@ -88,9 +88,9 @@ export const fetchSupplierPerformance = async < webId: WebId, ): Promise => { try { - const artifacts = await fetchQueryArtifacts({ - query: "supplierPerformance", - webIds: [webId], + const artifacts = await fetchAnalysisArtifacts({ + analysis: "supplierPerformance", + webId, }); const perfRef = artifacts.performance; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx similarity index 96% rename from apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx rename to apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx index 81a3cc755f2..82c649bc67f 100644 --- a/apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx +++ b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx @@ -12,7 +12,7 @@ import type { ReactElement, ReactNode } from "react"; /** * Layout shared by every `/supply-chain/*` page. Mounts the ported * value-chain-timing `AppShell` inside hash's sidebar chrome, scoped to the - * active web — the gateway transport queries `/api/query` for that `webId`. + * active web — the gateway transport calls `/api/analysis` for that `webId`. * * The subtree is wrapped in `.hash-ds-root` so the ds-components Panda tokens * resolve, and that element is supplied as the `PortalContainerContext` so ds diff --git a/apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id].page.tsx similarity index 100% rename from apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx rename to apps/hash-frontend/src/pages/supply-chain.page/site/[site-id].page.tsx diff --git a/apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx similarity index 100% rename from apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx rename to apps/hash-frontend/src/pages/supply-chain.page/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx diff --git a/apps/hash-frontend/src/shared/analysis-client.ts b/apps/hash-frontend/src/shared/analysis-client.ts new file mode 100644 index 00000000000..b6d53482f77 --- /dev/null +++ b/apps/hash-frontend/src/shared/analysis-client.ts @@ -0,0 +1,108 @@ +import { apiOrigin } from "@local/hash-isomorphic-utils/environment"; + +import type { + AnalysisInvocation, + AnalysisResponse, + AnalysisResult, + ArtifactRef, +} from "@local/hash-isomorphic-utils/analysis/types"; + +/** + * Client for the generic analysis gateway (`POST /api/analysis`). The gateway + * returns short-lived URLs; artifact bytes are fetched directly from storage + * (the data plane) rather than proxied through the API. + */ + +export class AnalysisError extends Error { + constructor(message: string) { + super(message); + this.name = "AnalysisError"; + } +} + +/** POST a batch of named-analysis invocations and return their results. */ +export const runAnalyses = async ( + requests: AnalysisInvocation[], +): Promise => { + const response = await fetch(`${apiOrigin}/api/analysis`, { + method: "POST", + credentials: "include", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ requests }), + }); + + if (!response.ok) { + throw new AnalysisError( + `Analysis request failed with status ${response.status}`, + ); + } + + const body = (await response.json()) as AnalysisResponse; + return body.results; +}; + +/** Fetch and JSON-parse the bytes referenced by a resolved artifact. */ +export const fetchArtifactJson = async (ref: ArtifactRef): Promise => { + // Presigned (S3) URLs carry auth in the query string and must NOT receive + // cookies; same-origin (local dev) URLs go through the API and need them. + const sameOrigin = ref.url.startsWith(apiOrigin); + const response = await fetch(ref.url, { + credentials: sameOrigin ? "include" : "omit", + }); + + if (!response.ok) { + throw new AnalysisError( + `Artifact "${ref.name}" fetch failed with status ${response.status}`, + ); + } + + return (await response.json()) as T; +}; + +const resultReady = (result: AnalysisResult | undefined): AnalysisResult => { + if (!result) { + throw new AnalysisError("Empty analysis response"); + } + if (result.status === "error") { + throw new AnalysisError(result.error ?? "Analysis returned an error"); + } + if (result.status !== "ready" || !result.artifacts?.length) { + throw new AnalysisError( + `Analysis result not ready (status: ${result.status})`, + ); + } + return result; +}; + +/** + * Run a single named analysis and return the parsed JSON of one of its + * artifacts (the primary/first by default, or the named one via `opts.artifact`). + */ +export const fetchAnalysisArtifact = async ( + invocation: Omit, + opts?: { artifact?: string }, +): Promise => { + const [result] = await runAnalyses([{ id: "a0", ...invocation }]); + const ready = resultReady(result); + + const ref = opts?.artifact + ? ready.artifacts!.find((a) => a.name === opts.artifact) + : ready.artifacts![0]; + + if (!ref) { + throw new AnalysisError( + `Artifact "${opts?.artifact ?? "(primary)"}" not present in result`, + ); + } + + return fetchArtifactJson(ref); +}; + +/** Like {@link fetchAnalysisArtifact} but resolves multiple named artifacts at once. */ +export const fetchAnalysisArtifacts = async ( + invocation: Omit, +): Promise> => { + const [result] = await runAnalyses([{ id: "a0", ...invocation }]); + const ready = resultReady(result); + return Object.fromEntries(ready.artifacts!.map((ref) => [ref.name, ref])); +}; diff --git a/apps/hash-frontend/src/shared/telemetry-client.ts b/apps/hash-frontend/src/shared/telemetry-client.ts new file mode 100644 index 00000000000..175164f8e40 --- /dev/null +++ b/apps/hash-frontend/src/shared/telemetry-client.ts @@ -0,0 +1,62 @@ +import { v4 as uuid } from "uuid"; + +import { apiOrigin } from "@local/hash-isomorphic-utils/environment"; + +import type { TelemetryRequest } from "@local/hash-isomorphic-utils/telemetry/types"; + +/** + * Client for the telemetry gateway (`POST /api/telemetry`). The server stamps + * all trusted fields (identity, IP, environment); the browser only supplies an + * allowlisted event name, optional properties, and an anonymous id for + * logged-out continuity. Telemetry must never break the app, so all failures + * are swallowed. + */ +const ANONYMOUS_ID_STORAGE_KEY = "hash-telemetry-anonymous-id"; + +/** Generate/persist an opaque anonymous id for logged-out -> logged-in stitching. */ +const getAnonymousId = (): string | undefined => { + if (typeof window === "undefined") { + return undefined; + } + try { + let id = window.localStorage.getItem(ANONYMOUS_ID_STORAGE_KEY); + if (!id) { + id = uuid(); + window.localStorage.setItem(ANONYMOUS_ID_STORAGE_KEY, id); + } + return id; + } catch { + // localStorage can be unavailable (private mode, blocked cookies). + return undefined; + } +}; + +/** Send a batch of allowlisted events. Fire-and-forget; never throws. */ +export const sendTelemetry = ( + payload: Omit, +): void => { + if (typeof window === "undefined" || payload.events.length === 0) { + return; + } + + const body: TelemetryRequest = { + ...payload, + anonymousId: getAnonymousId(), + }; + + void fetch(`${apiOrigin}/api/telemetry`, { + method: "POST", + credentials: "include", + // `keepalive` lets the request outlive a page transition/unload. + keepalive: true, + headers: { "content-type": "application/json" }, + body: JSON.stringify(body), + }).catch(() => { + // Swallow: telemetry failures must never surface to the user. + }); +}; + +/** Report a page view. */ +export const trackPageView = (path: string): void => { + sendTelemetry({ events: [{ type: "page", name: path }] }); +}; diff --git a/libs/@local/hash-isomorphic-utils/src/query/types.ts b/libs/@local/hash-isomorphic-utils/src/analysis/types.ts similarity index 56% rename from libs/@local/hash-isomorphic-utils/src/query/types.ts rename to libs/@local/hash-isomorphic-utils/src/analysis/types.ts index 52f1d51008c..879e2340cac 100644 --- a/libs/@local/hash-isomorphic-utils/src/query/types.ts +++ b/libs/@local/hash-isomorphic-utils/src/analysis/types.ts @@ -1,32 +1,33 @@ import type { WebId } from "@blockprotocol/type-system"; /** - * Wire types for the generic query gateway (`POST /api/query`). + * Wire types for the generic analysis gateway (`POST /api/analysis`). * - * The gateway resolves *named queries* (registered server-side) to one or more + * The gateway resolves *named analyses* (registered server-side) to one or more * stored artifacts and returns short-lived URLs the client fetches directly * from storage. The same contract supports a future live-compute path: a result * may come back as `computing` rather than `ready` without any client change. */ -/** A single named-query invocation within a batch request. */ -export interface QueryInvocation { +/** A single named-analysis invocation within a batch request. */ +export interface AnalysisInvocation { /** Caller-chosen id used to correlate this invocation with its result. */ id: string; - /** Registered query name, e.g. `"productGraph"`. */ - query: string; - /** Query-specific arguments; validated server-side against the query. */ + /** Registered analysis name, e.g. `"productGraph"`. */ + analysis: string; + /** Analysis-specific arguments; validated server-side against the analysis. */ args?: Record; /** - * Web(s) the query is scoped to. The authenticated actor must hold a role in - * every listed web, otherwise the whole invocation is rejected. + * Web the analysis is scoped to. The authenticated actor must hold a role in + * this web, otherwise the invocation is rejected. Batch multiple invocations + * to target several webs in one request. */ - webIds: WebId[]; + webId: WebId; } -/** Request body for `POST /api/query`. */ -export interface QueryRequest { - requests: QueryInvocation[]; +/** Request body for `POST /api/analysis`. */ +export interface AnalysisRequest { + requests: AnalysisInvocation[]; } /** A resolved artifact the client can fetch directly from storage. */ @@ -43,13 +44,13 @@ export interface ArtifactRef { expiresAt?: string; } -export type QueryResultStatus = "ready" | "computing" | "error"; +export type AnalysisResultStatus = "ready" | "computing" | "error"; -/** The result of a single {@link QueryInvocation}. */ -export interface QueryResult { +/** The result of a single {@link AnalysisInvocation}. */ +export interface AnalysisResult { /** Echoes the invocation `id`. */ id: string; - status: QueryResultStatus; + status: AnalysisResultStatus; /** Present when `status === "ready"`. */ artifacts?: ArtifactRef[]; /** Present when `status === "computing"`: hint for the client poll interval. */ @@ -58,7 +59,7 @@ export interface QueryResult { error?: string; } -/** Response body for `POST /api/query`. */ -export interface QueryResponse { - results: QueryResult[]; +/** Response body for `POST /api/analysis`. */ +export interface AnalysisResponse { + results: AnalysisResult[]; } diff --git a/libs/@local/hash-isomorphic-utils/src/telemetry/types.ts b/libs/@local/hash-isomorphic-utils/src/telemetry/types.ts new file mode 100644 index 00000000000..a4dcabe9fe7 --- /dev/null +++ b/libs/@local/hash-isomorphic-utils/src/telemetry/types.ts @@ -0,0 +1,53 @@ +/** + * Wire types for the telemetry gateway (`POST /api/telemetry`). + * + * The server is the only thing that talks to Rudderstack. The browser POSTs an + * allowlisted set of events here; the server stamps all trusted fields (user + * identity, IP, environment) and forwards them, flagging everything as + * `frontendProvided`. + */ + +/** + * Telemetry environments. Events are stamped with this so they remain + * queryable even within a single Rudderstack source (the separate per-env write + * keys are the primary boundary). + */ +export type TelemetryEnvironment = "development" | "staging" | "production"; + +/** + * Track-event names the browser is permitted to report. The server enforces + * this allowlist, so the frontend can never name a server-only event (e.g. + * `analysis_run`). Defined as a runtime constant so the server can validate + * against it and the type stays in sync. + */ +export const frontendTrackEventNames = [ + "supply_chain_product_viewed", + "supply_chain_site_viewed", + "supply_chain_opportunity_opened", +] as const; + +export type FrontendTrackEventName = (typeof frontendTrackEventNames)[number]; + +/** A single event reported by the browser. */ +export type FrontendTelemetryEvent = + | { + type: "page"; + /** Page path/name, e.g. `/supply-chain/product/abc`. */ + name: string; + properties?: Record; + } + | { + type: "track"; + name: FrontendTrackEventName; + properties?: Record; + }; + +/** Request body for `POST /api/telemetry`. */ +export interface TelemetryRequest { + /** + * Opaque client-generated id used to correlate logged-out activity, and to + * stitch it to a user once they authenticate. + */ + anonymousId?: string; + events: FrontendTelemetryEvent[]; +} diff --git a/yarn.lock b/yarn.lock index fb5650319de..0747f4f5f2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -503,7 +503,6 @@ __metadata: "@ory/kratos-client": "npm:25.4.0" "@rudderstack/rudder-sdk-node": "npm:3.0.8" "@sentry/node": "npm:10.54.0" - "@snowplow/node-tracker": "npm:4.8.2" "@temporalio/client": "npm:1.18.1" "@temporalio/proto": "npm:1.18.1" "@types/app-root-path": "npm:3.1.0" @@ -14756,26 +14755,6 @@ __metadata: languageName: node linkType: hard -"@snowplow/node-tracker@npm:4.8.2": - version: 4.8.2 - resolution: "@snowplow/node-tracker@npm:4.8.2" - dependencies: - "@snowplow/tracker-core": "npm:4.8.2" - tslib: "npm:^2.3.1" - checksum: 10c0/8a7538ce8f4b0cfd2b2a2c8e8dd6a6a5c69273ac698a4a8a387ec2bb4f623b2e2f6b0e983bd69ba85bb92ef3c7987ce87b3dd6066620a311f01973a079da7950 - languageName: node - linkType: hard - -"@snowplow/tracker-core@npm:4.8.2": - version: 4.8.2 - resolution: "@snowplow/tracker-core@npm:4.8.2" - dependencies: - tslib: "npm:^2.3.1" - uuid: "npm:^10.0.0" - checksum: 10c0/2d77d04d8aaef85685459a663b4d82e9f6e27ae99e4a6b7c442afd2b97aa8688b2bcb6c646f00e681d6d2c848fe819c5e841e173d7ec1b48ace7b3427917d922 - languageName: node - linkType: hard - "@so-ric/colorspace@npm:^1.1.6": version: 1.1.6 resolution: "@so-ric/colorspace@npm:1.1.6" @@ -41408,15 +41387,6 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^10.0.0": - version: 10.0.0 - resolution: "uuid@npm:10.0.0" - bin: - uuid: dist/bin/uuid - checksum: 10c0/eab18c27fe4ab9fb9709a5d5f40119b45f2ec8314f8d4cf12ce27e4c6f4ffa4a6321dc7db6c515068fa373c075b49691ba969f0010bf37f44c37ca40cd6bf7fe - languageName: node - linkType: hard - "uuid@npm:^13.0.0": version: 13.0.2 resolution: "uuid@npm:13.0.2" From 464a4321138964d4940499fdf52e4ae34e8f919f Mon Sep 17 00:00:00 2001 From: Ciaran Morinan Date: Fri, 26 Jun 2026 14:16:52 +0100 Subject: [PATCH 03/21] comment cleanup --- apps/hash-frontend/panda.config.ts | 6 +++--- .../shared/supply-chain-analysis-requests.ts | 6 +----- .../pages/supply-chain.page/shared/supply-chain-layout.tsx | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/apps/hash-frontend/panda.config.ts b/apps/hash-frontend/panda.config.ts index fd54756261b..3946b601b72 100644 --- a/apps/hash-frontend/panda.config.ts +++ b/apps/hash-frontend/panda.config.ts @@ -22,12 +22,12 @@ export default defineConfig({ ...scopedThemeConfig(".hash-ds-root"), /** - * Styles used inside ds-components itself, plus the ported value-chain-timing - * supply-chain tool (`src/vct`) and its route pages, which author Panda - * `css()` calls against the ds-components preset tokens. + * Styles used inside ds-components itself, plus the supply-chain tool + * and its route pages, which author Panda `css()` calls against the ds-components preset tokens. */ include: [ require.resolve("@hashintel/ds-components/panda.buildinfo.json"), + /** @todo these will move */ "./src/vct/**/*.{ts,tsx}", "./src/pages/supply-chain/**/*.{ts,tsx}", ], diff --git a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts index 1a74e2481e8..cf43690f5c1 100644 --- a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts +++ b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-analysis-requests.ts @@ -7,11 +7,7 @@ import { import type { WebId } from "@blockprotocol/type-system"; /** - * Data-access layer for the supply-chain (value-chain-timing) views, ported - * from the standalone SPA's `shared/data.ts`. Where the SPA fetched static JSON - * from `/data/...`, these go through the auth-gated analysis gateway, scoped to - * a `webId`. View-layer payload types (graph, step detail, site summary) are - * supplied by the caller as type parameters during the component migration. + * Data-access layer for the supply-chain views. */ /** A product as listed in `products.json`. */ diff --git a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx index 82c649bc67f..3fa2859490c 100644 --- a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx +++ b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx @@ -10,14 +10,12 @@ import { useActiveWorkspace } from "../../shared/workspace-context"; import type { ReactElement, ReactNode } from "react"; /** - * Layout shared by every `/supply-chain/*` page. Mounts the ported - * value-chain-timing `AppShell` inside hash's sidebar chrome, scoped to the - * active web — the gateway transport calls `/api/analysis` for that `webId`. + * Layout shared by every `/supply-chain/*` page. * * The subtree is wrapped in `.hash-ds-root` so the ds-components Panda tokens * resolve, and that element is supplied as the `PortalContainerContext` so ds * and Ark overlays (dialogs, tooltips, selects) portal *inside* the token - * scope rather than at `document.body` (mirrors the standalone tool's `_app`). + * scope rather than at `document.body`. * * `AppShell` is keyed by the active web so switching workspace remounts it and * reloads the product/site registry for the new scope. From c1c30e6b669e6d2f209baa787df97baa3caa5dbe Mon Sep 17 00:00:00 2001 From: Ciaran Morinan Date: Fri, 26 Jun 2026 14:17:31 +0100 Subject: [PATCH 04/21] comment cleanup --- .../pages/supply-chain.page/shared/supply-chain-layout.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx index 3fa2859490c..2f3e27ba947 100644 --- a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx +++ b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx @@ -26,12 +26,6 @@ const SupplyChainShell = ({ children }: { children: ReactNode }) => { return ( - {/* - Bound the ds scope to the viewport height below hash's global header so - the ported AppShell (which fills this box with `height:100%`) can scroll - its content pane internally instead of overflowing the page. This is the - host-side counterpart to the standalone tool's `100dvh` `.vct-root`. - */}
Date: Sat, 27 Jun 2026 11:56:07 +0100 Subject: [PATCH 05/21] file organisation, fix ts and linting --- apps/hash-api/package.json | 2 +- ...ion.ts => 027-add-petri-nets.migration.ts} | 0 .../028-add-supply-chain-types.migration.ts | 263 ++ .../src/telemetry/telemetry-endpoint.test.ts | 8 +- apps/hash-frontend/package.json | 4 +- apps/hash-frontend/panda.config.ts | 2 - apps/hash-frontend/src/pages/_app.page.tsx | 7 +- .../src/pages/shared/workspace-context.tsx | 17 +- .../src/pages/supply-chain.page.tsx | 16 +- .../shared/supply-chain-layout.tsx | 54 - .../supply-chain.page/site/[site-id].page.tsx | 22 - .../[product-id]/[step-id].page.tsx | 36 - .../src/pages/supply-chain/README.md | 131 + .../supply-chain/app-shell/opportunity.tsx | 2146 ++++++++++++++ .../app-shell/opportunity/brief-charts.tsx | 372 +++ .../opportunity/opportunity-utils.test.ts | 455 +++ .../opportunity/opportunity-utils.ts | 1552 ++++++++++ .../opportunity/recommendation-playbook.ts | 435 +++ .../pages/supply-chain/app-shell/product.tsx | 612 ++++ .../app-shell/product/category-view.tsx | 262 ++ .../app-shell/product/e2e-what-if.tsx | 356 +++ .../product/e2e-what-if/binding-lever.tsx | 282 ++ .../app-shell/product/e2e-what-if/caveats.ts | 166 ++ .../product/e2e-what-if/what-if-kpis.tsx | 110 + .../app-shell/product/process-graph.tsx | 328 +++ .../product/process-graph/step-node.tsx | 38 + .../product/recompute-batch-timelines.ts | 209 ++ .../product/shared/category-icon.tsx | 155 + .../product/shared/pipeline-header.tsx | 174 ++ .../product/shared/pipeline-waterfall.tsx | 385 +++ .../app-shell/product/shared/step-card.tsx | 696 +++++ .../app-shell/product/whatif.test.ts | 382 +++ .../supply-chain/app-shell/product/whatif.ts | 929 ++++++ .../src/pages/supply-chain/app-shell/site.tsx | 651 +++++ .../app-shell/site/category-filter.tsx | 94 + .../app-shell/site/dashboard-card.tsx | 208 ++ .../app-shell/site/dwell-table.tsx | 185 ++ .../app-shell/site/mini-toggle.tsx | 54 + .../app-shell/site/opportunities-table.tsx | 602 ++++ .../app-shell/site/opportunities.test.ts | 198 ++ .../app-shell/site/opportunities.ts | 293 ++ .../app-shell/site/planning-table.tsx | 244 ++ .../app-shell/site/shared/helpers.ts | 258 ++ .../site/shared/low-sample-badge.tsx | 36 + .../app-shell/site/shared/product-tags.tsx | 32 + .../app-shell/site/shared/row-types.ts | 49 + .../app-shell/site/shared/site-node-key.ts | 11 + .../app-shell/site/shared/sort-header.tsx | 63 + .../app-shell/site/shared/table-styles.ts | 130 + .../site/site-monthly-carry-cost-chart.tsx | 111 + .../app-shell/site/supplier-table.tsx | 213 ++ .../app-shell/site/tab-button.tsx | 41 + .../app-shell/site/trend-table.tsx | 274 ++ .../app-shell/site/use-site-overview-rows.ts | 318 +++ .../site/use-supply-chain-status-state.ts | 481 ++++ .../app-shell/site/vendor-detail-panel.tsx | 367 +++ .../product/[product-id].page.tsx | 33 +- .../shared/action-button-styles.ts | 40 + .../supply-chain/shared/action-buttons.tsx | 124 + .../carrying-cost.characterization.test.ts | 88 + .../pages/supply-chain/shared/categories.ts | 101 + .../supply-chain/shared/chart-format.test.ts | 16 + .../pages/supply-chain/shared/chart-format.ts | 61 + .../pages/supply-chain/shared/chart-kit.tsx | 183 ++ .../pages/supply-chain/shared/chart-theme.ts | 51 + .../pages/supply-chain/shared/cost.test.ts | 131 + .../src/pages/supply-chain/shared/cost.ts | 183 ++ .../pages/supply-chain/shared/data-table.tsx | 161 ++ .../src/pages/supply-chain/shared/data.ts | 170 ++ .../supply-chain/shared/detail-date-key.ts | 47 + .../supply-chain/shared/docs/docs-content.tsx | 65 + .../docs/docs-content/opportunity-brief.tsx | 105 + .../docs/docs-content/product-overview.tsx | 279 ++ .../shared/docs/docs-content/settings.tsx | 120 + .../docs/docs-content/site-overview.tsx | 210 ++ .../shared/docs/docs-content/step-detail.tsx | 118 + .../shared/docs/docs-content/step-dwell.tsx | 86 + .../docs/docs-content/step-procurement.tsx | 55 + .../docs/docs-content/step-production.tsx | 47 + .../shared/docs/docs-content/step-qa.tsx | 31 + .../shared/docs/docs-content/step-transit.tsx | 31 + .../supply-chain/shared/docs/docs-context.tsx | 25 + .../supply-chain/shared/docs/docs-modal.tsx | 367 +++ .../shared/docs/docs-primitives.tsx | 296 ++ .../supply-chain/shared/docs/docs-types.ts | 40 + .../supply-chain/shared/docs/use-docs.ts | 14 + .../pages/supply-chain/shared/export-utils.ts | 45 + .../supply-chain/shared/feature-flags.ts | 43 + .../supply-chain/shared/header-actions.tsx | 287 ++ .../pages/supply-chain/shared/load-state.tsx | 45 + .../shared/measure-context.test.ts | 56 + .../supply-chain/shared/measure-context.ts | 88 + .../supply-chain/shared/node-badges.test.ts | 74 + .../supply-chain/shared/normalize-contract.ts | 323 +++ .../shared/observation-fixtures.ts | 98 + .../supply-chain/shared/observation-labels.ts | 137 + .../shared/outlier-selection.test.ts | 121 + .../supply-chain/shared/outlier-selection.ts | 257 ++ .../shared/outlier-selection/iqr.test.ts | 61 + .../shared/outlier-selection/iqr.ts | 73 + .../supply-chain/shared/period-trends.test.ts | 232 ++ .../supply-chain/shared/period-trends.ts | 316 +++ .../supply-chain/shared/planning-param.ts | 31 + .../pages/supply-chain/shared/plant-label.ts | 40 + .../shared/procurement-basis-context.ts | 40 + .../shared/procurement-basis.test.ts | 140 + .../shared/procurement-observations.ts | 116 + .../supply-chain/shared/range-filter.test.ts | 89 + .../pages/supply-chain/shared/range-filter.ts | 496 ++++ .../shared/records-derive.test.ts | 257 ++ .../supply-chain/shared/registry-context.ts | 25 + .../supply-chain/shared/scope-context.ts | 20 + .../supply-chain/shared/scope-select.tsx | 65 + .../supply-chain/shared/searchable-select.tsx | 231 ++ .../supply-chain/shared/segmented-control.tsx | 81 + .../shared/site-aggregation.test.ts | 283 ++ .../supply-chain/shared/site-aggregation.ts | 197 ++ .../pages/supply-chain/shared/slide-over.tsx | 142 + .../pages/supply-chain/shared/stat-chip.tsx | 53 + .../pages/supply-chain/shared/stats.test.ts | 25 + .../src/pages/supply-chain/shared/stats.ts | 66 + .../supply-chain/shared/status-dialog.tsx | 286 ++ .../supply-chain/shared/status-graph-types.ts | 46 + .../supply-chain/shared/step-detail-panel.tsx | 915 ++++++ .../step-detail-panel/consumption-metrics.tsx | 406 +++ .../step-detail-panel/data-table-section.tsx | 753 +++++ .../step-detail-panel/distribution-chart.tsx | 325 +++ .../step-detail-panel/monthly-cost-chart.tsx | 159 ++ .../step-detail-panel/savings-calculator.tsx | 348 +++ .../step-detail-panel/step-detail-format.ts | 31 + .../step-detail-primitives.tsx | 500 ++++ .../step-detail-panel/time-series-chart.tsx | 250 ++ .../step-detail-panel/timing-metrics.tsx | 264 ++ .../step-detail-panel/yield-metrics.tsx | 172 ++ .../shared/supplier-dimension-view.tsx | 354 +++ .../supply-chain/shared/supplier-otif.test.ts | 229 ++ .../supply-chain/shared/supplier-otif.ts | 400 +++ .../shared/supply-chain-analysis-requests.ts | 48 +- .../shared/supply-chain-layout.tsx | 103 + .../src/pages/supply-chain/shared/tabs.tsx | 75 + .../pages/supply-chain/shared/telemetry.ts | 53 + .../supply-chain/shared/time-range-context.ts | 27 + .../supply-chain/shared/time-range.test.ts | 31 + .../pages/supply-chain/shared/time-range.ts | 42 + .../supply-chain/shared/toolbar-checkbox.tsx | 48 + .../src/pages/supply-chain/shared/tooltip.tsx | 143 + .../supply-chain/shared/trend-indicator.tsx | 81 + .../pages/supply-chain/shared/trend-tone.ts | 14 + .../src/pages/supply-chain/shared/types.ts | 676 +++++ .../supply-chain/shared/use-search-params.ts | 59 + .../supply-chain/shared/use-site-nodes.ts | 63 + .../supply-chain/shared/vendor-cards.tsx | 305 ++ .../supply-chain/shared/wire-contract.test.ts | 218 ++ .../supply-chain/site/[site-id].page.tsx | 46 + .../[product-id]/[step-id].page.tsx | 58 + .../supply-chain/supply-chain-data-shell.tsx | 386 +++ .../supply-chain-implementation-plan.md | 557 ++++ .../layout/layout-with-sidebar/sidebar.tsx | 22 +- .../src/ontology-type-ids.ts | 2485 ++++++++++++++++- .../src/telemetry/types.ts | 7 +- yarn.lock | 1 + 161 files changed, 34263 insertions(+), 173 deletions(-) rename apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/{091-add-petri-nets.dev.migration.ts => 027-add-petri-nets.migration.ts} (100%) create mode 100644 apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/028-add-supply-chain-types.migration.ts delete mode 100644 apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx delete mode 100644 apps/hash-frontend/src/pages/supply-chain.page/site/[site-id].page.tsx delete mode 100644 apps/hash-frontend/src/pages/supply-chain.page/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/README.md create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/brief-charts.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/recommendation-playbook.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/category-view.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/binding-lever.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/caveats.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/what-if-kpis.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph/step-node.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/recompute-batch-timelines.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/category-icon.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/pipeline-header.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/pipeline-waterfall.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/step-card.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/whatif.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/product/whatif.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/category-filter.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/dashboard-card.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/dwell-table.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/mini-toggle.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities-table.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/planning-table.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/helpers.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/low-sample-badge.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/product-tags.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/row-types.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/site-node-key.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/sort-header.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/table-styles.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/site-monthly-carry-cost-chart.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/supplier-table.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/tab-button.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/trend-table.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-site-overview-rows.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-supply-chain-status-state.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/app-shell/site/vendor-detail-panel.tsx rename apps/hash-frontend/src/pages/{supply-chain.page => supply-chain}/product/[product-id].page.tsx (75%) create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/action-button-styles.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/action-buttons.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/carrying-cost.characterization.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/categories.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/chart-format.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/chart-format.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/chart-kit.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/chart-theme.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/cost.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/cost.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/data-table.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/data.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/detail-date-key.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/opportunity-brief.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/product-overview.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/settings.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/site-overview.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-detail.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-dwell.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-procurement.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-production.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-qa.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-transit.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-context.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-modal.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-primitives.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-types.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/docs/use-docs.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/export-utils.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/feature-flags.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/header-actions.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/load-state.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/measure-context.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/measure-context.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/node-badges.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/normalize-contract.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/observation-fixtures.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/observation-labels.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/period-trends.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/period-trends.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/planning-param.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/plant-label.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis-context.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/procurement-observations.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/range-filter.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/range-filter.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/records-derive.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/registry-context.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/scope-context.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/scope-select.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/searchable-select.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/segmented-control.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/slide-over.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/stat-chip.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/stats.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/stats.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/status-dialog.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/status-graph-types.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/consumption-metrics.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/data-table-section.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/distribution-chart.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/monthly-cost-chart.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/savings-calculator.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/step-detail-format.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/step-detail-primitives.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/time-series-chart.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/timing-metrics.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/step-detail-panel/yield-metrics.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/supplier-dimension-view.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/supplier-otif.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/supplier-otif.ts rename apps/hash-frontend/src/pages/{supply-chain.page => supply-chain}/shared/supply-chain-analysis-requests.ts (69%) create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/supply-chain-layout.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/tabs.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/telemetry.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/time-range-context.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/time-range.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/time-range.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/toolbar-checkbox.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/tooltip.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/trend-indicator.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/trend-tone.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/types.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/use-search-params.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/use-site-nodes.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/vendor-cards.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/shared/wire-contract.test.ts create mode 100644 apps/hash-frontend/src/pages/supply-chain/site/[site-id].page.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/supply-chain-data-shell.tsx create mode 100644 apps/hash-frontend/src/pages/supply-chain/supply-chain-implementation-plan.md diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index 7062103f72d..a4e0a68b6ba 100644 --- a/apps/hash-api/package.json +++ b/apps/hash-api/package.json @@ -12,7 +12,7 @@ "dev:seed-crm-data": "NODE_ENV=development tsx ./src/seed-data/seed-crm-data.ts", "fix:eslint": "eslint --fix .", "generate-hash-gpt-schema": "tsx ./src/ai/gpt/generate-hashgpt-schema.ts", - "generate-ontology-type-ids": "tsx ./src/generate-ontology-type-ids.ts; oxfmt --write --ignore-path /dev/null ../../libs/@local/hash-isomorphic-utils/src/ontology-type-ids.ts", + "generate-ontology-type-ids": "tsx ./src/generate-ontology-type-ids.ts; cd ../../libs/@local/hash-isomorphic-utils && oxfmt --write --ignore-path /dev/null src/ontology-type-ids.ts", "lint:eslint": "eslint --report-unused-disable-directives .", "lint:tsc": "tsc --noEmit", "setup:admin": "NODE_ENV=production OTEL_SERVICE_NAME=\"Setup Admin\" tsx --import ./src/instrument.mjs ./src/setup-admin.ts", diff --git a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/091-add-petri-nets.dev.migration.ts b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/027-add-petri-nets.migration.ts similarity index 100% rename from apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/091-add-petri-nets.dev.migration.ts rename to apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/027-add-petri-nets.migration.ts diff --git a/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/028-add-supply-chain-types.migration.ts b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/028-add-supply-chain-types.migration.ts new file mode 100644 index 00000000000..5432db4d1d3 --- /dev/null +++ b/apps/hash-api/src/graph/ensure-system-graph-is-initialized/migrate-ontology-types/migrations/028-add-supply-chain-types.migration.ts @@ -0,0 +1,263 @@ +import { blockProtocolPropertyTypes } from "@local/hash-isomorphic-utils/ontology-type-ids"; + +import { + createSystemEntityTypeIfNotExists, + createSystemPropertyTypeIfNotExists, + getCurrentHashDataTypeId, +} from "../util"; + +import type { MigrationFunction } from "../types"; + +const migrate: MigrationFunction = async ({ + context, + authentication, + migrationState, +}) => { + const datetimeDataTypeId = getCurrentHashDataTypeId({ + dataTypeKey: "datetime", + migrationState, + }); + + const productIdPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Product ID", + description: "The identifier of a product in a supply-chain dataset.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const siteIdPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Site ID", + description: "The identifier of a site in a supply-chain dataset.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const stepIdPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Step ID", + description: + "The identifier of a product step in a supply-chain dataset.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const opportunityTypePropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Opportunity Type", + description: + "The broad type of a supply-chain opportunity, such as dwell or planning.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const opportunityKindPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Opportunity Kind", + description: + "The specific kind of supply-chain opportunity a status or preference refers to.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const scopeKeyPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Scope Key", + description: + "A stable key identifying a supply-chain product step or opportunity scope.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const statusCategoryPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Status Category", + description: "The category assigned to a supply-chain status report.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const statusTextPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Status Text", + description: "The text of a supply-chain status report.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const authorIdPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Status Report Author ID", + description: + "The identifier of the user who created a supply-chain status report.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }, + ); + + const createdAtPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Status Report Created At", + description: + "The date and time at which a supply-chain status report was created.", + possibleValues: [{ dataTypeId: datetimeDataTypeId }], + }, + migrationState, + webShortname: "h", + }, + ); + + const readMarkersPropertyType = await createSystemPropertyTypeIfNotExists( + context, + authentication, + { + propertyTypeDefinition: { + title: "Supply Chain Read Markers", + description: + "The supply-chain opportunity scopes a user has marked as read.", + possibleValues: [{ primitiveDataType: "object", array: true }], + }, + migrationState, + webShortname: "h", + }, + ); + + const preferencesUserIdPropertyType = + await createSystemPropertyTypeIfNotExists(context, authentication, { + propertyTypeDefinition: { + title: "Supply Chain Preferences User ID", + description: + "The identifier of the user whose supply-chain preferences are stored.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }); + + const preferencesWebIdPropertyType = + await createSystemPropertyTypeIfNotExists(context, authentication, { + propertyTypeDefinition: { + title: "Supply Chain Preferences Web ID", + description: + "The identifier of the web the supply-chain preferences apply to.", + possibleValues: [{ primitiveDataType: "text" }], + }, + migrationState, + webShortname: "h", + }); + + await createSystemEntityTypeIfNotExists(context, authentication, { + entityTypeDefinition: { + title: "Supply Chain Status Report", + titlePlural: "Supply Chain Status Reports", + description: + "An authored status update for a supply-chain product step or opportunity.", + labelProperty: scopeKeyPropertyType.metadata.recordId.baseUrl, + properties: [ + { propertyType: scopeKeyPropertyType.schema.$id, required: true }, + { propertyType: productIdPropertyType.schema.$id, required: true }, + { propertyType: siteIdPropertyType.schema.$id, required: true }, + { propertyType: stepIdPropertyType.schema.$id, required: true }, + { + propertyType: opportunityTypePropertyType.schema.$id, + required: true, + }, + { propertyType: opportunityKindPropertyType.schema.$id }, + { propertyType: statusCategoryPropertyType.schema.$id, required: true }, + { propertyType: statusTextPropertyType.schema.$id }, + { propertyType: authorIdPropertyType.schema.$id, required: true }, + { propertyType: createdAtPropertyType.schema.$id, required: true }, + ], + }, + migrationState, + webShortname: "h", + }); + + await createSystemEntityTypeIfNotExists(context, authentication, { + entityTypeDefinition: { + title: "Supply Chain User Preferences", + titlePlural: "Supply Chain User Preferences", + description: + "User-scoped preferences for supply-chain views in a HASH web.", + labelProperty: blockProtocolPropertyTypes.name.propertyTypeBaseUrl, + properties: [ + { + propertyType: blockProtocolPropertyTypes.name.propertyTypeId, + required: true, + }, + { + propertyType: preferencesUserIdPropertyType.schema.$id, + required: true, + }, + { + propertyType: preferencesWebIdPropertyType.schema.$id, + required: true, + }, + { propertyType: readMarkersPropertyType.schema.$id }, + ], + }, + migrationState, + webShortname: "h", + }); + + return migrationState; +}; + +export default migrate; diff --git a/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts b/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts index 8567a484074..35a65944f4f 100644 --- a/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts +++ b/apps/hash-api/src/telemetry/telemetry-endpoint.test.ts @@ -15,13 +15,13 @@ describe("parseTelemetryEvent", () => { expect( parseTelemetryEvent({ type: "track", - name: "supply_chain_product_viewed", - properties: { productId: "abc" }, + name: "supply_chain_interaction", + properties: { interaction: "product_step_selected", productId: "abc" }, }), ).toEqual({ type: "track", - name: "supply_chain_product_viewed", - properties: { productId: "abc" }, + name: "supply_chain_interaction", + properties: { interaction: "product_step_selected", productId: "abc" }, }); }); diff --git a/apps/hash-frontend/package.json b/apps/hash-frontend/package.json index e4c170964cb..4db4f27191b 100644 --- a/apps/hash-frontend/package.json +++ b/apps/hash-frontend/package.json @@ -16,7 +16,8 @@ "start": "next start", "start:healthcheck": "wait-on --timeout 1200000 http://localhost:3000", "start:test": "next start", - "start:test:healthcheck": "wait-on --timeout 600000 http://localhost:3000" + "start:test:healthcheck": "wait-on --timeout 600000 http://localhost:3000", + "test:unit": "vitest run" }, "dependencies": { "@ai-sdk/openai": "3.0.63", @@ -169,6 +170,7 @@ "rimraf": "6.1.3", "sass": "1.93.2", "typescript": "5.9.3", + "vitest": "4.1.8", "wait-on": "9.0.1", "webpack": "5.104.1" } diff --git a/apps/hash-frontend/panda.config.ts b/apps/hash-frontend/panda.config.ts index 3946b601b72..549b9a7c5df 100644 --- a/apps/hash-frontend/panda.config.ts +++ b/apps/hash-frontend/panda.config.ts @@ -27,8 +27,6 @@ export default defineConfig({ */ include: [ require.resolve("@hashintel/ds-components/panda.buildinfo.json"), - /** @todo these will move */ - "./src/vct/**/*.{ts,tsx}", "./src/pages/supply-chain/**/*.{ts,tsx}", ], diff --git a/apps/hash-frontend/src/pages/_app.page.tsx b/apps/hash-frontend/src/pages/_app.page.tsx index 90c8fc01d18..f3e982280fa 100644 --- a/apps/hash-frontend/src/pages/_app.page.tsx +++ b/apps/hash-frontend/src/pages/_app.page.tsx @@ -335,10 +335,9 @@ const featureFlagHiddenPathnames: Record = { ai: ["/goals"], supplyChain: [ "/supply-chain", - "/supply-chain/methodology", - "/supply-chain/product/[productId]", - "/supply-chain/site/[siteId]", - "/supply-chain/site/[siteId]/opportunity/[opportunityType]/[productId]/[stepId]", + "/supply-chain/product/[product-id]", + "/supply-chain/site/[site-id]", + "/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id]", ], }; diff --git a/apps/hash-frontend/src/pages/shared/workspace-context.tsx b/apps/hash-frontend/src/pages/shared/workspace-context.tsx index 88bea94c66a..922db32b6ad 100644 --- a/apps/hash-frontend/src/pages/shared/workspace-context.tsx +++ b/apps/hash-frontend/src/pages/shared/workspace-context.tsx @@ -66,11 +66,15 @@ export const WorkspaceContextProvider: FunctionComponent<{ if (localStorageInitialValue) { setActiveWorkspaceWebId(localStorageInitialValue as WebId); } else if (authenticatedUser) { + const defaultWorkspaceWebId = + authenticatedUser.memberOf[0]?.org.webId ?? + (authenticatedUser.accountId as WebId); + /** - * Initialize the `activeWorkspaceWebId` to the account ID of the - * currently authenticated user + * Initialize the `activeWorkspaceWebId` to the first organization the + * user belongs to, falling back to the user's account web. */ - updateActiveWorkspaceWebId(authenticatedUser.accountId as WebId); + updateActiveWorkspaceWebId(defaultWorkspaceWebId); } } }, [activeWorkspaceWebId, updateActiveWorkspaceWebId, authenticatedUser]); @@ -86,10 +90,13 @@ export const WorkspaceContextProvider: FunctionComponent<{ /** * If there is an `activeWorkspaceWebId` and an `authenticatedUser`, but * `activeWorkspace` is not defined, reset `activeWorkspaceWebId` to the - * authenticated user's account ID + * default workspace. */ if (activeWorkspaceWebId && authenticatedUser && !activeWorkspace) { - updateActiveWorkspaceWebId(authenticatedUser.accountId as WebId); + updateActiveWorkspaceWebId( + authenticatedUser.memberOf[0]?.org.webId ?? + (authenticatedUser.accountId as WebId), + ); } return { diff --git a/apps/hash-frontend/src/pages/supply-chain.page.tsx b/apps/hash-frontend/src/pages/supply-chain.page.tsx index fbdbdf4e716..f80d97170a4 100644 --- a/apps/hash-frontend/src/pages/supply-chain.page.tsx +++ b/apps/hash-frontend/src/pages/supply-chain.page.tsx @@ -1,23 +1,29 @@ import { useRouter } from "next/router"; import { useEffect } from "react"; -import { useRegistry } from "./supply-chain.page/shared/registry-contextry-context"; -import { getSupplyChainLayout } from "./supply-chain.page/shared/supply-chain-layoutupply-chain-layout"; +import { useRegistry } from "./supply-chain/shared/registry-context"; +import { getSupplyChainLayout } from "./supply-chain/shared/supply-chain-layout"; import type { NextPageWithLayout } from "../shared/layout"; -/** Supply-chain landing: send to the first product. */ +/** Supply-chain landing: send to the first site, falling back to a product. */ const SupplyChainIndexPage: NextPageWithLayout = () => { const router = useRouter(); - const { products } = useRegistry(); + const { products, sites } = useRegistry(); useEffect(() => { + const firstSite = sites[0]; + if (firstSite) { + void router.replace(`/supply-chain/site/${firstSite.slug}`); + return; + } + const firstProduct = products[0]; if (!firstProduct) { return; } void router.replace(`/supply-chain/product/${firstProduct.id}`); - }, [products, router]); + }, [products, router, sites]); return null; }; diff --git a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx b/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx deleted file mode 100644 index 2f3e27ba947..00000000000 --- a/apps/hash-frontend/src/pages/supply-chain.page/shared/supply-chain-layout.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { useRef } from "react"; - -import { PortalContainerContext } from "@hashintel/ds-components"; - -import { getLayoutWithSidebar } from "../../../shared/layout"; -import { HEADER_HEIGHT } from "../../../shared/layout/layout-with-header/page-header"; -import { AppShell } from "../../../vct/supply-chain/app-shell"; -import { useActiveWorkspace } from "../../shared/workspace-context"; - -import type { ReactElement, ReactNode } from "react"; - -/** - * Layout shared by every `/supply-chain/*` page. - * - * The subtree is wrapped in `.hash-ds-root` so the ds-components Panda tokens - * resolve, and that element is supplied as the `PortalContainerContext` so ds - * and Ark overlays (dialogs, tooltips, selects) portal *inside* the token - * scope rather than at `document.body`. - * - * `AppShell` is keyed by the active web so switching workspace remounts it and - * reloads the product/site registry for the new scope. - */ -const SupplyChainShell = ({ children }: { children: ReactNode }) => { - const rootRef = useRef(null); - const { activeWorkspaceWebId } = useActiveWorkspace(); - - return ( - -
- {activeWorkspaceWebId ? ( - - {children} - - ) : null} -
-
- ); -}; - -export const getSupplyChainLayout = (page: ReactElement): ReactNode => - getLayoutWithSidebar({page}, { - fullWidth: true, - }); diff --git a/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id].page.tsx deleted file mode 100644 index a53a8d1e730..00000000000 --- a/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id].page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { useRouter } from "next/router"; - -import { useRegistry } from "../../../vct/supply-chain/shared/registry-context"; -import { SiteOverview } from "../../../vct/supply-chain/site"; -import { getSupplyChainLayout } from "../shared/supply-chain-layout"; - -import type { NextPageWithLayout } from "../../../shared/layout"; - -const SitePage: NextPageWithLayout = () => { - const router = useRouter(); - const { products, sites } = useRegistry(); - const siteId = - typeof router.query["site-id"] === "string" - ? router.query["site-id"] - : (sites[0]?.slug ?? ""); - - return ; -}; - -SitePage.getLayout = getSupplyChainLayout; - -export default SitePage; diff --git a/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx deleted file mode 100644 index ae973d04f23..00000000000 --- a/apps/hash-frontend/src/pages/supply-chain.page/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id].page.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { useRouter } from "next/router"; - -import { OpportunityBrief } from "../../../../../../../vct/supply-chain/opportunity"; -import { useRegistry } from "../../../../../../../vct/supply-chain/shared/registry-context"; -import { getSupplyChainLayout } from "../../../../../shared/supply-chain-layout"; - -import type { NextPageWithLayout } from "../../../../../../../shared/layout"; -import type { OpportunityType } from "../../../../../../../vct/supply-chain/opportunity/opportunity-utils"; - -const normaliseOpportunityType = (value: string | undefined): OpportunityType => - value === "planning" ? "planning" : "dwell"; - -const OpportunityPage: NextPageWithLayout = () => { - const router = useRouter(); - const { products, sites } = useRegistry(); - const query = router.query as { - "site-id"?: string; - "opportunity-type"?: string; - "product-id"?: string; - "step-id"?: string; - }; - - return ( - - ); -}; - -OpportunityPage.getLayout = getSupplyChainLayout; - -export default OpportunityPage; diff --git a/apps/hash-frontend/src/pages/supply-chain/README.md b/apps/hash-frontend/src/pages/supply-chain/README.md new file mode 100644 index 00000000000..6f1838ead15 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/README.md @@ -0,0 +1,131 @@ +# Supply Chain + +The supply-chain pages provide workspace-scoped analysis views for products, +sites, steps, opportunities, and status reports. The route resolves the HASH web +that contains a populated supply-chain dataset before rendering the app shell, so +users are not stranded on an empty personal web when an organization web has the +data. + +## Feature Surfaces + +### Site Overview + +The site overview is reached at `/supply-chain/site/[site-id]`. It shows a +site-level view across products, including opportunity tables, dwell and +planning views, trend information, supplier performance when enabled, contextual +docs, settings, step detail panels, and status reporting. + +Status reports are shared within the resolved data web. Read/unread state is +user-specific and stored through a supply-chain preferences entity for the user +and web, rather than as one graph entity per read marker. + +### Product Overview + +The product overview is reached at `/supply-chain/product/[product-id]`. It +shows the product graph, category view, route and pipeline views, step detail +panels, contextual docs, and analysis settings. The selected step and settings +are URL-backed where appropriate so route transitions and reloads preserve the +view state. + +### Opportunity Brief + +The opportunity brief route is +`/supply-chain/site/[site-id]/opportunity/[opportunity-type]/[product-id]/[step-id]`. +It gives focused context for a dwell or planning opportunity without changing +the shared status/read state model. + +## Telemetry + +Supply-chain telemetry is intentionally grouped into a small allowlist of event +names, with richer properties describing the interaction. Do not add ad hoc +event names for individual buttons or controls. + +Allowed event names: + +- `supply_chain_viewed` +- `supply_chain_interaction` +- `supply_chain_status_report_created` +- `supply_chain_error` + +Supported properties: + +- `interaction` +- `source` +- `route` +- `productId` +- `siteId` +- `stepId` +- `opportunityType` +- `opportunityKind` + +Do not send status report free text, display names, customer names, site or +product display labels, raw analysis values, or client-specific data. + +## Covered Events + +### Views + +- Product page viewed: `supply_chain_viewed` with `route`, `productId`, and + `source`. +- Site page viewed: `supply_chain_viewed` with `route`, `siteId`, and `source`. +- Opportunity brief viewed: `supply_chain_viewed` with `route`, `siteId`, + `productId`, `stepId`, `opportunityType`, and `source`. + +### Interactions + +- `docs_opened` +- `status_dialog_opened` +- `site_step_selected` +- `site_tab_changed` +- `product_step_selected` +- `product_view_mode_changed` +- `opportunity_marked_read` +- `opportunity_marked_unread` +- `wacc_changed` +- `storage_cost_changed` +- `outliers_excluded` +- `outliers_included` +- `measure_changed` +- `procurement_basis_changed` +- `time_range_changed` + +### Status Reports + +- Creating a status report sends `supply_chain_status_report_created` with + `siteId`, `productId`, `stepId`, `opportunityType`, and `source`. +- Status report text is never sent. +- User display names are never sent. + +### Handled Errors + +Sentry catches uncaught thrown errors. The telemetry error event is for errors +that the supply-chain UI catches and handles itself. + +Currently covered handled errors: + +- `product_graph_fetch_failed`: product graph fetch failed and the product page + rendered an error state. +- `status_report_create_failed`: status report creation failed after an + optimistic UI update, and the status history was reloaded. + +Currently not covered by `supply_chain_error`: + +- Dataset web resolution failures that fall back to the empty-state view. +- Registry loading failures handled by `SupplyChainDataShell`. +- Step detail panel fetch failures handled inside the panel. +- Opportunity brief fetch failures handled inside the brief view. +- Site-node loading failures handled by site overview hooks. +- Supplier performance fetch failures that degrade to no supplier data. +- Fullscreen request/exit failures that are intentionally ignored. + +If one of these handled failures becomes important to analyze, add a +`supply_chain_error` event with an `interaction` value describing the failed +operation and only non-sensitive IDs as context. + +## Known Telemetry Gaps + +- Track the "show read" opportunity toggle. +- Track brief-link clicks. +- Add the selected tab value to `site_tab_changed`. +- Track scope picker changes. +- Track table filtering and sorting once those interactions are stable. diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity.tsx new file mode 100644 index 00000000000..3079d0f1adc --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity.tsx @@ -0,0 +1,2146 @@ +import { useCallback, useEffect, useMemo, useState } from "react"; + +import { Button } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { DocsIconButton } from "../shared/action-buttons"; +import { + useCostParams, + useOutlierSetting, + formatCost, + formatNumber, +} from "../shared/cost"; +import { fetchStepDetail, fetchSiteSummary } from "../shared/data"; +import { detailDateKeyFromColumns } from "../shared/detail-date-key"; +import { useDocs } from "../shared/docs/use-docs"; +import { buildCsvContent, downloadCsv } from "../shared/export-utils"; +import { LoadingState, ErrorState } from "../shared/load-state"; +import { applyOutlierSelectionToStep } from "../shared/outlier-selection"; +import { + computePeriodDeltas, + computeCostComparison, +} from "../shared/period-trends"; +import { useProcurementBasis } from "../shared/procurement-basis-context"; +import { + filterGraphNodeByDateRange, + filterStepByDateRange, + applyProcurementBasisToStep, +} from "../shared/range-filter"; +import { + cutoffForRange, + timeRangeLongLabel, + type TimeRange, +} from "../shared/time-range"; +import { useTimeRange } from "../shared/time-range-context"; +import { TrendIndicator } from "../shared/trend-indicator"; +import { useSearchParams } from "../shared/use-search-params"; +import { useSiteNodes } from "../shared/use-site-nodes"; +import { + BriefBoxPlot, + BriefHistogram, + BriefSparkline, +} from "./opportunity/brief-charts"; +import { + buildDwellOpportunityBrief, + buildPlanningOpportunityBrief, + firstProductForNode, + type DwellOpportunityBrief, + type OpportunityBriefSourceKind, + type PlanningOpportunityBrief, + type OpportunityType, + type ProductNodeRef, + type SupplierBriefSummary, + type ProductionInsight, + type BriefEvidenceRow, + type FirstUseDwellSummary, +} from "./opportunity/opportunity-utils"; + +import type { + Product, + SiteNode, + StepDetail, + DetailRows, + SiteSummaryRollups, +} from "../shared/types"; + +const SM = "@media (min-width: 640px)"; + +const article = css({ + mx: "auto", + maxW: "[1024px]", + px: "6", + py: "8", + color: "fg.heading", +}); +const topBar = css({ + mb: "6", + display: "flex", + alignItems: "center", + justifyContent: "flex-end", + gap: "4", +}); +const topActions = css({ display: "flex", alignItems: "center", gap: "2" }); +const briefScrollArea = css({ + h: "full", + minH: "0", + overflowY: "auto", + "@media print": { + h: "auto", + overflow: "visible", + }, +}); +const headerEl = css({ + borderBottomWidth: "1px", + borderColor: "fg.heading", + pb: "5", +}); +const eyebrow = css({ + mb: "3", + display: "flex", + flexWrap: "wrap", + alignItems: "center", + gap: "2", + textStyle: "xs", + fontWeight: "medium", + textTransform: "uppercase", + letterSpacing: "[0.12em]", + color: "fg.muted", +}); +const eyebrowDot = css({ + h: "1", + w: "1", + borderRadius: "full", + bg: "fg.subtle", +}); +const h1 = css({ + fontFamily: "display", + textStyle: "3xl", + fontWeight: "medium", + lineHeight: "[1.25]", +}); +const metaGrid = css({ + mt: "3", + display: "grid", + gap: "2", + textStyle: "sm", + color: "fg.muted", + alignItems: "start", + [SM]: { gridTemplateColumns: "[repeat(2,minmax(0,1fr))]" }, +}); +const metaStack = css({ display: "flex", flexDirection: "column", gap: "2" }); +const metricsSection = css({ + display: "grid", + gap: "4", + py: "5", + [SM]: { gridTemplateColumns: "[repeat(3,minmax(0,1fr))]" }, +}); +const triggerCard = css({ + mb: "4", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "[#fafafa]", + p: "4", +}); +const triggerTop = css({ + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", + gap: "4", + flexWrap: "wrap", +}); +const triggerEyebrow = css({ + textStyle: "xs", + fontWeight: "semibold", + textTransform: "uppercase", + letterSpacing: "[0.08em]", + color: "fg.muted", +}); +const triggerMetric = css({ + textStyle: "xl", + fontWeight: "semibold", + fontVariantNumeric: "tabular-nums", + color: "fg.heading", +}); +const triggerReason = css({ + mt: "2", + textStyle: "sm", + lineHeight: "[1.625]", + color: "fg.heading", +}); +const triggerChip = css({ + display: "inline-flex", + alignItems: "center", + borderRadius: "full", + bg: "bgSolid.min", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + px: "2.5", + py: "1", + textStyle: "xs", + color: "fg.muted", + whiteSpace: "nowrap", +}); +const grid3Mt = css({ + mt: "4", + display: "grid", + gap: "3", + [SM]: { gridTemplateColumns: "[repeat(3,minmax(0,1fr))]" }, +}); +const distGrid = css({ + display: "grid", + gap: "3", + [SM]: { gridTemplateColumns: "[repeat(3,minmax(0,1fr))]" }, +}); +const evidenceBox = css({ + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + p: "3", +}); +const evidenceHeading = css({ + mb: "2", + textStyle: "xs", + fontWeight: "semibold", + textTransform: "uppercase", + letterSpacing: "[0.08em]", + color: "fg.muted", +}); +const evidenceStack = css({ + display: "flex", + flexDirection: "column", + gap: "2", +}); +const evidenceFlag = css({ borderRadius: "md", bg: "bg.subtle", p: "2" }); +const flagLabelWarn = css({ + textStyle: "xs", + fontWeight: "semibold", + color: "status.warning.fg.body", +}); +const flagLabelDefault = css({ + textStyle: "xs", + fontWeight: "semibold", + color: "fg.muted", +}); +const flagDetail = css({ + mt: "0.5", + textStyle: "xs", + lineHeight: "[1.625]", + color: "fg.muted", +}); +const evidenceEmpty = css({ textStyle: "sm", color: "fg.muted" }); +const impactWrap = css({ + overflowX: "auto", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", +}); +const briefTable = css({ w: "full", textStyle: "sm", lineHeight: "normal" }); +const impactThead = css({ + bg: "[#fafafa]", + textAlign: "left", + textStyle: "xs", + fontWeight: "medium", + textTransform: "uppercase", + letterSpacing: "[0.08em]", + color: "fg.muted", + borderBottomWidth: "1px", + borderColor: "[#d9d9d9]", +}); +const cellTh = css({ px: "3", py: "2" }); +const cellThRight = css({ px: "3", py: "2", textAlign: "right" }); +const tbodyDivide = css({ + "& > tr": { borderTopWidth: "1px", borderColor: "[#f0f0f0]" }, + "& > tr:first-child": { borderTopWidth: "0" }, +}); +const cellTd = css({ px: "3", py: "2" }); +const cellTdRight = css({ + px: "3", + py: "2", + textAlign: "right", + fontVariantNumeric: "tabular-nums", +}); +const cellTdSaving = css({ + px: "3", + py: "2", + textAlign: "right", + fontVariantNumeric: "tabular-nums", + fontWeight: "medium", + color: "status.success.fg.body", +}); +const scenarioLabel = css({ fontWeight: "medium", color: "fg.heading" }); +const scenarioRationale = css({ textStyle: "xs", color: "fg.muted" }); +const grid4 = css({ + display: "grid", + gap: "3", + [SM]: { gridTemplateColumns: "[repeat(4,minmax(0,1fr))]" }, +}); +const optionCard = css({ + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + p: "3", +}); +const optionLabel = css({ + textStyle: "xs", + fontWeight: "medium", + color: "fg.muted", +}); +const optionDays = css({ + mt: "1", + textStyle: "xl", + fontWeight: "semibold", + fontVariantNumeric: "tabular-nums", +}); +const optionDesc = css({ + mt: "2", + textStyle: "xs", + lineHeight: "[1.625]", + color: "fg.muted", +}); +const grid2Mt = css({ + mt: "4", + display: "grid", + gap: "3", + [SM]: { gridTemplateColumns: "[repeat(2,minmax(0,1fr))]" }, +}); +const nsGridBase = css({ display: "grid", gap: "3" }); +const nsCols1 = css({ + [SM]: { gridTemplateColumns: "[repeat(1,minmax(0,1fr))]" }, +}); +const nsCols2 = css({ + [SM]: { gridTemplateColumns: "[repeat(2,minmax(0,1fr))]" }, +}); +const nsCols3 = css({ + [SM]: { gridTemplateColumns: "[repeat(3,minmax(0,1fr))]" }, +}); +const nextStepsEmpty = css({ textStyle: "sm", color: "fg.muted" }); +const sectionEl = css({ + borderTopWidth: "1px", + borderColor: "bd.subtle", + py: "5", +}); +const sectionTitle = css({ + mb: "3", + textStyle: "base", + fontWeight: "semibold", + color: "fg.heading", +}); +const metricCard = css({ + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bgSolid.min", + p: "3", +}); +const metricLabel = css({ + textStyle: "xs", + fontWeight: "medium", + color: "fg.muted", +}); +const metricValue = css({ + mt: "1", + textStyle: "xl", + fontWeight: "semibold", + fontVariantNumeric: "tabular-nums", + color: "fg.heading", +}); +const metricBad = css({ color: "status.error.fg.body" }); +const metricGood = css({ color: "status.success.fg.body" }); +const metricWarning = css({ color: "status.warning.fg.body" }); +const metricTrendWrap = css({ mt: "1.5", textStyle: "xs" }); +const metricTrendNote = css({ color: "fg.subtle" }); +const checklistCard = css({ + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + p: "3", +}); +const checklistTitle = css({ + textStyle: "sm", + fontWeight: "semibold", + color: "fg.heading", +}); +const guidanceGrid = css({ mb: "4", display: "grid", gap: "3" }); +const calloutCard = css({ borderRadius: "lg", bg: "[#fafafa]", p: "3" }); +// Confidence Assessment: bordered like the executive-summary callout, with top +// margin to separate it from the opportunity-diagnosis bullets above. +const confidenceCallout = css({ + mt: "4", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "[#fafafa]", + p: "3", +}); +const calloutTitle = css({ + textStyle: "sm", + fontWeight: "semibold", + color: "fg.heading", +}); +const calloutBody = css({ + mt: "1", + textStyle: "sm", + lineHeight: "[1.625]", + color: "fg.muted", +}); +const bulletList = css({ + listStyleType: "disc", + pl: "5", + textStyle: "sm", + lineHeight: "[1.625]", + color: "fg.muted", + "& > li + li": { mt: "1" }, +}); +const checklistBulletMt = css({ mt: "2" }); +const statTableWrap = css({ + overflow: "hidden", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", +}); +const statTdLabel = css({ + px: "3", + py: "2", + color: "fg.muted", + whiteSpace: "nowrap", +}); +const statTdValue = css({ + px: "3", + py: "2", + textAlign: "right", + fontWeight: "medium", + fontVariantNumeric: "tabular-nums", + color: "fg.heading", + whiteSpace: "nowrap", +}); +const stackedValue = css({ + display: "inline-flex", + flexDirection: "column", + alignItems: "flex-end", + gap: "0.5", + whiteSpace: "nowrap", +}); +const metaTerm = css({ fontWeight: "medium", color: "fg.heading" }); +const errorPad = css({ px: "6", py: "8" }); +const labelWithBadge = css({ + display: "inline-flex", + flexWrap: "wrap", + alignItems: "center", + gap: "1.5", +}); +const offRecipeBadge = css({ + display: "inline-flex", + alignItems: "center", + borderRadius: "full", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "status.warning.bd.subtle", + bg: "status.warning.bg.subtle", + color: "status.warning.fg.body", + px: "2", + py: "0.5", + textStyle: "xxs", + fontWeight: "medium", + whiteSpace: "nowrap", +}); +const leverageCallout = css({ + mb: "4", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + p: "3", + display: "grid", + gap: "1", +}); +const leverageTitle = css({ + textStyle: "xs", + fontWeight: "semibold", + textTransform: "uppercase", + letterSpacing: "[0.08em]", + color: "fg.muted", +}); +const leverageBody = css({ + textStyle: "sm", + lineHeight: "[1.625]", + color: "fg.heading", +}); +const firstUseNote = css({ + mt: "3", + textStyle: "sm", + lineHeight: "[1.625]", + color: "fg.heading", +}); +const provenanceText = css({ + mt: "2", + textStyle: "xs", + lineHeight: "[1.5]", + color: "fg.subtle", +}); +const subTableNote = css({ mt: "2", textStyle: "xs", color: "fg.muted" }); +const topEvidenceWrap = css({ + mt: "4", + display: "flex", + flexDirection: "column", + gap: "2", +}); +const chartsGrid = css({ + mb: "4", + display: "grid", + gap: "4", + [SM]: { gridTemplateColumns: "[repeat(3,minmax(0,1fr))]" }, +}); +const metricCue = css({ fontSize: "[0.75em]" }); +const srOnly = css({ + position: "absolute", + w: "[1px]", + h: "[1px]", + p: "0", + m: "[-1px]", + overflow: "hidden", + clip: "[rect(0,0,0,0)]", + whiteSpace: "nowrap", + borderWidth: "0", +}); +const heroBanner = css({ + mb: "4", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "[#fafafa]", + p: "4", + display: "grid", + gap: "2", +}); +const heroTop = css({ + display: "flex", + flexWrap: "wrap", + alignItems: "baseline", + justifyContent: "space-between", + gap: "3", +}); +const heroPrize = css({ + textStyle: "2xl", + fontWeight: "semibold", + fontVariantNumeric: "tabular-nums", + color: "fg.heading", +}); +const heroPrizeLabel = css({ + textStyle: "xs", + fontWeight: "medium", + textTransform: "uppercase", + letterSpacing: "[0.08em]", + color: "fg.muted", +}); +const heroAction = css({ + textStyle: "sm", + lineHeight: "[1.625]", + color: "fg.heading", +}); +const heroRank = css({ + display: "inline-flex", + alignItems: "center", + borderRadius: "full", + bg: "bgSolid.min", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + px: "2.5", + py: "1", + textStyle: "xs", + color: "fg.muted", + whiteSpace: "nowrap", +}); + +interface OpportunityBriefProps { + products: Product[]; + siteId: string; + productId: string; + stepId: string; + opportunityType: OpportunityType; +} + +function formatDeviation(value: number | null): string { + if (value == null) { + return "-"; + } + return `${value > 0 ? "+" : ""}${formatNumber(value, { maximumFractionDigits: 0 })}%`; +} + +function formatDaysAndDeviation( + days: number | null, + deviation: number | null, +): string { + return `${formatNumber(days, { maximumFractionDigits: 1 })}d / ${formatDeviation(deviation)}`; +} + +function formatExceedingPlan(brief: PlanningOpportunityBrief): string { + if (brief.pctExceedingPlan == null) { + return "-"; + } + const count = + brief.nExceedingPlan == null ? "–" : formatNumber(brief.nExceedingPlan); + return `${count} / ${formatNumber(brief.pctExceedingPlan, { maximumFractionDigits: 0 })}%`; +} + +function toneForDeviation(value: number | null): "bad" | "good" | "neutral" { + if (value == null) { + return "neutral"; + } + if (value > 0) { + return "bad"; + } + if (value < 0) { + return "good"; + } + return "neutral"; +} + +function formatTrendSummary( + trend: { + pctChange: number | null; + currentValue: number | null; + previousValue: number | null; + currentN: number; + previousN: number; + }, + range: TimeRange, +): string { + if ( + trend.pctChange == null || + trend.currentValue == null || + trend.previousValue == null + ) { + return `No comparison (${formatNumber(trend.currentN)} current / ${formatNumber(trend.previousN)} previous samples)`; + } + return `${formatNumber(trend.currentValue, { maximumFractionDigits: 1 })}d vs ${formatNumber(trend.previousValue, { maximumFractionDigits: 1 })}d previous ${range} (${formatDeviation(trend.pctChange)})`; +} + +const HighestCostMonthValue = ({ brief }: { brief: DwellOpportunityBrief }) => { + if (!brief.highestCostMonth) { + return "-"; + } + return ( + + {brief.highestCostMonth.month} + + {formatCost(brief.highestCostMonth.cost, brief.currency, { + compact: true, + })} + + + ); +}; + +const BriefSection = ({ + title, + children, +}: { + title: string; + children: React.ReactNode; +}) => { + return ( +
+

{title}

+ {children} +
+ ); +}; + +interface TrendChip { + pctChange: number | null; + /** Last-period value, formatted for display. */ + previous: string; +} + +/** Build a headline trend chip, or null when there's no comparable prior period. */ + +const MetricCard = ({ + label, + value, + tone = "neutral", + trend, +}: { + label: string; + value: string; + tone?: "bad" | "good" | "neutral" | "warning"; + trend?: TrendChip | null; +}) => { + const cue = tone === "bad" ? "▲" : tone === "good" ? "▼" : null; + const cueLabel = + tone === "bad" + ? "unfavourable" + : tone === "good" + ? "favourable" + : tone === "warning" + ? "watch" + : null; + return ( +
+
{label}
+
+ {cue && ( + + {cue}{" "} + + )} + {value} + {cueLabel && ({cueLabel})} +
+ {trend && ( + + {trend.previous} + last period + + )} +
+ ); +}; + +const BulletList = ({ + items, + className, +}: { + items: string[]; + className?: string; +}) => { + return ( +
    + {items.map((item) => ( +
  • {item}
  • + ))} +
+ ); +}; +const Checklist = ({ title, items }: { title: string; items: string[] }) => { + return ( +
+

{title}

+ +
+ ); +}; +const Callout = ({ title, body }: { title: string; body: string }) => { + return ( +
+

{title}

+

{body}

+
+ ); +}; +const StatTable = ({ rows }: { rows: Array<[string, React.ReactNode]> }) => { + return ( +
+ + + {rows.map(([label, value]) => ( + + + + + ))} + +
{label}{value}
+
+ ); +}; + +const MetaLine = ({ label, value }: { label: string; value: string }) => { + return ( +
+ {label}: + {value || "-"} +
+ ); +}; + +function rankingText(ranking: BriefRanking): string { + const noun = ranking.kind === "dwell" ? "dwell cost" : "planning mismatch"; + const plural = ranking.total === 1 ? noun : `${noun}s`; + return `#${ranking.rank} of the plant's top ${ranking.total} ${plural}`; +} +const HeroBannerShell = ({ + prizeLabel, + prize, + action, + ranking, +}: { + prizeLabel: string; + prize: string; + action: string; + ranking: BriefRanking | null; +}) => { + return ( +
+
+
+
{prizeLabel}
+
{prize}
+
+ {ranking && {rankingText(ranking)}} +
+

{action}

+
+ ); +}; +const ConfidenceBadge = ({ label }: { label: "High" | "Limited" | "Low" }) => { + const className = cx( + triggerChip, + label === "High" + ? css({ + bg: "status.success.bg.subtle", + borderColor: "status.success.bd.subtle", + color: "status.success.fg.body", + fontWeight: "semibold", + }) + : label === "Limited" + ? css({ + bg: "status.warning.bg.subtle", + borderColor: "status.warning.bd.subtle", + color: "status.warning.fg.body", + fontWeight: "semibold", + }) + : css({ + bg: "status.error.bg.subtle", + borderColor: "status.error.bd.subtle", + color: "status.error.fg.body", + fontWeight: "semibold", + }), + ); + return Confidence: {label}; +}; +const DwellExecutiveSummary = ({ + brief, + timeRange, +}: { + brief: DwellOpportunityBrief; + timeRange: TimeRange; +}) => { + const moderate = + brief.scenarios.find((scenario) => scenario.label === "Moderate") ?? + brief.scenarios[0]; + return ( +
+ + + + + +
+ ); +}; +const PlanningExecutiveSummary = ({ + brief, +}: { + brief: PlanningOpportunityBrief; +}) => { + return ( +
+ + + + + + + + + 20 ? "bad" : "neutral"} + /> +
+ ); +}; +const DwellImpactSection = ({ + brief, + currency, +}: { + brief: DwellOpportunityBrief; + currency: string | null; +}) => { + return ( + +
+ + + + + + + + + + + + {brief.scenarios.map((scenario) => ( + + + + + + + + ))} + +
ScenarioTarget dwellReductionPeriod savingAnnualized saving
+
{scenario.label}
+
+ {scenario.approximate ? "Approximate: " : ""} + {scenario.rationale} +
+
+ {formatNumber(scenario.targetDays, { + maximumFractionDigits: 1, + })} + d + + {formatNumber(scenario.reductionPct * 100, { + maximumFractionDigits: 0, + })} + % + + {formatCost(scenario.periodSaving, currency, { + compact: true, + })} + + {formatCost(scenario.annualizedSaving, currency, { + compact: true, + })} +
+
+
+ ); +}; + +const PlanningImpactTable = ({ + brief, +}: { + brief: PlanningOpportunityBrief; +}) => { + if (brief.calibrationImpact.length === 0) { + return null; + } + return ( +
+
+ + + + + + + + + + + {brief.calibrationImpact.map((row) => ( + + + + + + + ))} + +
TargetDaysBuffer vs planLate-event risk
+
{row.label}
+
{row.description}
+
+ {formatNumber(row.days, { maximumFractionDigits: 1 })}d + + {row.bufferDaysVsPlan == null + ? "-" + : `${row.bufferDaysVsPlan > 0 ? "+" : ""}${formatNumber(row.bufferDaysVsPlan, { maximumFractionDigits: 1 })}d`} + + {row.pctExceeding == null + ? "-" + : `${formatNumber(row.pctExceeding, { maximumFractionDigits: 0 })}%`} +
+
+

+ Buffer vs plan is the planning days released (positive) or added + (negative) by adopting each target. Late-event risk is the share of + observed events that would still exceed the target. +

+
+ ); +}; +const PlanningRecommendationSection = ({ + brief, +}: { + brief: PlanningOpportunityBrief; +}) => { + return ( + +
+ {brief.serviceLevelOptions.map((option) => ( +
+
{option.label}
+
+ {formatNumber(option.days, { maximumFractionDigits: 1 })}d +
+

{option.description}

+
+ ))} +
+ +
+ + + +
+
+ ); +}; +const E2ELeverageSection = ({ brief }: { brief: DwellOpportunityBrief }) => { + const lev = brief.e2eLeverage; + if (!lev) { + return null; + } + const share = formatNumber(lev.bindingSharePct, { maximumFractionDigits: 0 }); + const marginal = formatNumber(lev.expectedMarginalPerDay, { + maximumFractionDigits: 2, + }); + const lowLeverage = lev.expectedMarginalPerDay < 0.2; + const next = + lev.nextBottleneckLabel && lev.nextBottleneckDays != null + ? ` After about ${formatNumber(lev.nextBottleneckDays, { maximumFractionDigits: 1 })}d of reduction, ${lev.nextBottleneckLabel} becomes the binding constraint.` + : ""; + return ( + +
+
+ Does reducing this step move the end-to-end lead time? +
+

+ This step is on the binding (critical) chain in {share}% of batches, + and each day removed yields about {marginal} end-to-end days.{next} + {lowLeverage + ? " Marginal end-to-end leverage is low, so treat the headline saving as a local carrying-cost reduction rather than a lead-time win." + : ""} +

+
+
+ ); +}; +const PerProductImpactSection = ({ + brief, +}: { + brief: DwellOpportunityBrief; +}) => { + const rows = brief.perProductImpact; + if (rows.length === 0) { + return null; + } + return ( + +
+ + + + + + + + + + + + {rows.map((row) => ( + + + + + + + + ))} + +
Consuming product / materialkg-daysEst. costShareEvents
+ + {row.label} + {row.inCurrentRecipe === false && ( + + not in current recipe + + )} + + + {formatNumber(row.kgDays, { + compact: true, + maximumFractionDigits: 1, + })} + + {formatCost(row.periodCost, brief.currency, { + compact: true, + })} + + {formatNumber(row.sharePct, { maximumFractionDigits: 0 })}% + {formatNumber(row.events)}
+
+

+ Impact is split by the immediate consuming material; an intermediate may + appear instead of the finished good. +

+
+ ); +}; +const FirstUseDwellSection = ({ + firstUse, + verb, +}: { + firstUse: FirstUseDwellSummary; + verb: "order" | "produce"; +}) => { + return ( + +
+ + + + + = 60 + ? "warning" + : "neutral" + } + /> +
+

{firstUse.note}

+
+ ); +}; +const SupplierSection = ({ supplier }: { supplier: SupplierBriefSummary }) => { + return ( + +
+ + + + + + + + + + + + {supplier.vendors.map((value) => ( + + + + + + + + ))} + +
VendorOTIFMean days late≥7d lateLines
{value.name} + {value.otifPct == null + ? "-" + : `${formatNumber(value.otifPct, { maximumFractionDigits: 0 })}%`} + + {value.meanDaysLateAll == null + ? "-" + : `${formatNumber(value.meanDaysLateAll, { maximumFractionDigits: 1 })}d`} + + {value.ge7dPct == null + ? "-" + : `${formatNumber(value.ge7dPct, { maximumFractionDigits: 0 })}%`} + {formatNumber(value.nLines)}
+
+ {supplier.worstEvents.length > 0 && ( + <> +

+ Worst late deliveries in the selected period: +

+ + `${event.materialName ?? "Material"} from ${event.vendorName ?? "unknown vendor"}${event.poNumber ? ` (PO ${event.poNumber})` : ""}: ${formatNumber(event.daysLate, { maximumFractionDigits: 0 })}d late${event.date ? ` (${event.date})` : ""}`, + )} + /> + + )} + {supplier.dataQualityNote && ( +

{supplier.dataQualityNote}

+ )} +
+ ); +}; +const ProductionInsightSection = ({ + insight, +}: { + insight: ProductionInsight; +}) => { + const items = [insight.yield, insight.consumption].filter( + (xValue): xValue is string => Boolean(xValue), + ); + if (items.length === 0) { + return null; + } + return ( + + + + ); +}; +const TopEvidenceTable = ({ rows }: { rows: BriefEvidenceRow[] }) => { + if (rows.length === 0) { + return null; + } + const showKg = rows.some((row) => row.kgDays != null); + const showDays = rows.some((row) => row.days != null); + return ( +
+

Largest contributors

+
+ + + + + + {showDays && } + {showKg && } + + + + {rows.map((row) => ( + + + + {showDays && ( + + )} + {showKg && ( + + )} + + ))} + +
ItemDateDayskg-days
{row.label}{row.date ?? "-"} + {row.days == null + ? "-" + : `${formatNumber(row.days, { maximumFractionDigits: 1 })}d`} + + {row.kgDays == null + ? "-" + : formatNumber(row.kgDays, { + compact: true, + maximumFractionDigits: 1, + })} +
+
+
+ ); +}; +interface BriefRanking { + rank: number; + total: number; + kind: "dwell" | "planning"; +} +function computeBriefRanking( + rollups: SiteSummaryRollups | null, + stepId: string, + isDwellBrief: boolean, +): BriefRanking | null { + if (!rollups) { + return null; + } + const list = isDwellBrief + ? rollups.top_dwell_costs + : rollups.top_planning_mismatches; + const idx = list.findIndex((row) => row.node_id === stepId); + if (idx < 0) { + return null; + } + return { + rank: idx + 1, + total: list.length, + kind: isDwellBrief ? "dwell" : "planning", + }; +} +const HeroBanner = ({ + brief, + ranking, +}: { + brief: DwellOpportunityBrief | PlanningOpportunityBrief; + ranking: BriefRanking | null; +}) => { + if (brief.kind === "dwell") { + const moderate = + brief.scenarios.find((step) => step.label === "Moderate") ?? + brief.scenarios[0]; + const prize = moderate?.annualizedSaving ?? null; + const prizeText = + prize != null + ? formatCost(prize, brief.currency, { compact: true }) + : brief.annualizedCost != null + ? formatCost(brief.annualizedCost, brief.currency, { compact: true }) + : "—"; + const prizeLabel = + prize != null + ? "Estimated annualized saving" + : "Annualized carrying cost"; + const action = moderate + ? `Cap recurring long dwell toward ${formatNumber(moderate.targetDays, { maximumFractionDigits: 1 })}d to release the bulk of this carrying cost.` + : "Investigate structural waiting time and handoffs to reduce carrying cost."; + return ( + + ); + } + const target = brief.p95Days; + const prizeText = + target != null + ? `${formatNumber(target, { maximumFractionDigits: 1 })}d` + : "—"; + const action = + brief.currentPlanDays != null && target != null + ? `${brief.calibrationDirection === "tighten" ? "Tighten" : "Re-set"} the plan from ${formatNumber(brief.currentPlanDays, { maximumFractionDigits: 1 })}d toward ${formatNumber(target, { maximumFractionDigits: 1 })}d at the service level the business wants to protect.` + : "Calibrate the planning parameter once more observations are available."; + return ( + + ); +}; +const OpportunityTriggerCallout = ({ + brief, +}: { + brief: DwellOpportunityBrief | PlanningOpportunityBrief; +}) => { + return ( +
+
+
+
{brief.opportunityTrigger.label}
+
+ {brief.opportunityTrigger.primaryMetric} +
+
+ +
+

{brief.opportunityTrigger.reason}

+
+ ); +}; +const BriefGuidance = ({ + brief, +}: { + brief: DwellOpportunityBrief | PlanningOpportunityBrief; +}) => { + return ( +
+ +
+ ); +}; +const StepTypeNextSteps = ({ + nextSteps, +}: { + nextSteps: { scm: string[]; opex: string[]; planning: string[] }; +}) => { + const buckets = [ + { title: "SCM", items: nextSteps.scm }, + { title: "Operational Excellence", items: nextSteps.opex }, + { title: "Planning", items: nextSteps.planning }, + ].filter((right) => right.items.length > 0); + if (buckets.length === 0) { + return ( +

+ No step-type-specific recommendations are configured. Use the + distribution and evidence rows to identify the highest-leverage levers + manually. +

+ ); + } + const gridCols = + buckets.length === 1 ? nsCols1 : buckets.length === 2 ? nsCols2 : nsCols3; + return ( +
+ {buckets.map((bucket) => ( + + ))} +
+ ); +}; +function makeTrendChip( + pctChange: number | null | undefined, + previous: string | null, +): TrendChip | null { + if (previous == null) { + return null; + } + return { pctChange: pctChange ?? null, previous }; +} +function findBriefNode( + nodes: SiteNode[], + stepId: string, + productId: string, +): SiteNode | null { + return ( + nodes.find( + (node) => + node.id === stepId && + node.products.some((product) => product.id === productId), + ) ?? + nodes.find((node) => node.id === stepId) ?? + null + ); +} +function filterDetailRows( + rows: DetailRows, + dateKey: string, + range: TimeRange, +): Record[] { + const cutoff = cutoffForRange(range); + return rows.rows.filter((row) => { + const value = row[dateKey]; + return typeof value !== "string" || value.slice(0, 7) >= cutoff; + }); +} +const ConfidenceCallout = ({ + brief, +}: { + brief: DwellOpportunityBrief | PlanningOpportunityBrief; +}) => { + return ( +
+

Confidence Assessment

+

{brief.confidence.explanation}

+
+ ); +}; +function normaliseOpportunitySource( + value: string | null, +): OpportunityBriefSourceKind { + if ( + value === "planning_over" || + value === "planning_under" || + value === "dwell_cost" + ) { + return value; + } + return null; +} +export const OpportunityBrief = ({ + products, + siteId, + productId, + stepId, + opportunityType, +}: OpportunityBriefProps) => { + const { timeRange } = useTimeRange(); + const { waccRate, storageCost } = useCostParams(); + const { excludeOutliers } = useOutlierSetting(); + const { basis: procurementBasis } = useProcurementBasis(); + const { + nodes, + siteData, + loading: nodesLoading, + error: siteError, + } = useSiteNodes(siteId, products); + const [step, setStep] = useState(null); + const [stepError, setStepError] = useState(null); + const [rollups, setRollups] = useState(null); + const [searchParams] = useSearchParams(); + const { openDocs } = useDocs(); // Site rollups power the prioritisation chip in the hero banner ("#N of the + // plant's top dwell costs"). Failures degrade silently; the banner just omits + // the rank. + useEffect(() => { + let cancelled = false; + fetchSiteSummary(siteId) + .then((summary) => { + if (!cancelled) { + setRollups(summary?.rollups ?? null); + } + }) + .catch(() => { + if (!cancelled) { + setRollups(null); + } + }); + return () => { + cancelled = true; + }; + }, [siteId]); // Once the shared site nodes resolve, resolve the brief's node and fetch its + // step detail. The node lookup reuses the hook's memoised dedup. + useEffect(() => { + if (nodesLoading) { + return; + } + let cancelled = false; + const node = findBriefNode(nodes, stepId, productId); + const detailProductId = node + ? firstProductForNode(node, productId) + : productId; + fetchStepDetail(detailProductId, stepId) + .then((detail) => { + if (!cancelled) { + setStep(detail); + setStepError(null); + } + }) + .catch((event) => { + if (!cancelled) { + setStepError(event instanceof Error ? event.message : String(event)); + } + }); + return () => { + cancelled = true; + }; + }, [nodes, nodesLoading, productId, stepId]); + const error = siteError ?? stepError; + const siteNode = useMemo((): SiteNode | null => { + const node = findBriefNode(nodes, stepId, productId); + if (!node) { + return null; + } + return { + ...filterGraphNodeByDateRange( + node, + timeRange, + excludeOutliers, + procurementBasis, + ), + products: node.products, + }; + }, [nodes, stepId, productId, timeRange, excludeOutliers, procurementBasis]); // Each consuming product's own (pre-dedup) node for this material/step, so the + // brief can report per-product BOM membership and E2E binding leverage that the + // deduped site node alone cannot carry. + const productNodes = useMemo((): ProductNodeRef[] => { + if (!siteData) { + return []; + } + const refs: ProductNodeRef[] = []; + for (const { product, graph } of siteData.graphs) { + const match = graph.nodes.find((node) => { + if (node.type !== (siteNode?.type ?? node.type)) { + return false; + } + if (siteNode?.material) { + return node.material === siteNode.material; + } + return node.id === stepId; + }); + if (match) { + refs.push({ + productId: product.id, + productName: product.name, + node: match, + }); + } + } + return refs; + }, [siteData, siteNode, stepId]); + + const historicalStep = useMemo(() => { + if (!step) { + return null; + } + return applyOutlierSelectionToStep( + applyProcurementBasisToStep(step, procurementBasis), + excludeOutliers, + ); + }, [step, excludeOutliers, procurementBasis]); + + const filteredStep = useMemo(() => { + if (!step) { + return null; + } + return filterStepByDateRange( + step, + timeRange, + excludeOutliers, + procurementBasis, + ); + }, [step, timeRange, excludeOutliers, procurementBasis]); + + const brief = useMemo(() => { + if (!filteredStep || !historicalStep) { + return null; + } + if (opportunityType === "dwell") { + return buildDwellOpportunityBrief( + filteredStep, + historicalStep, + timeRange, + { waccRate, storageCost }, + { siteNode, productNodes }, + ); + } + return buildPlanningOpportunityBrief( + filteredStep, + historicalStep, + timeRange, + normaliseOpportunitySource(searchParams.get("op")), + ); + }, [ + filteredStep, + historicalStep, + opportunityType, + timeRange, + waccRate, + storageCost, + searchParams, + siteNode, + productNodes, + ]); + + const evidence = useMemo(() => { + if (!filteredStep?.detail_rows) { + return null; + } + const dateKey = detailDateKeyFromColumns( + filteredStep.detail_rows, + filteredStep.ref_date_col, + ); + const rows = dateKey + ? filterDetailRows(filteredStep.detail_rows, dateKey, timeRange) + : filteredStep.detail_rows.rows; + return { detailRows: filteredStep.detail_rows, rows, dateKey }; + }, [filteredStep, timeRange]); + + const handleEvidenceDownload = useCallback(() => { + if (!evidence || !filteredStep) { + return; + } + const csv = buildCsvContent(evidence.detailRows.columns, evidence.rows); + downloadCsv( + csv, + `${filteredStep.id}_${opportunityType}_brief_evidence.csv`, + ); + }, [evidence, filteredStep, opportunityType]); + + const handlePrint = useCallback(() => window.print(), []); + + if (error) { + return ; + } + + if (nodesLoading || !step) { + return ( + + ); + } + + if (!filteredStep || !historicalStep || !brief) { + return ( + + ); + } + + const productsForStep = + siteNode?.products ?? + products.filter((product) => product.id === productId); + const isDwellBrief = brief.kind === "dwell"; + const ranking = computeBriefRanking(rollups, stepId, isDwellBrief); + + // Headline period-over-period trends for median / P95 / cost (newest vs prior window). + const periodCmp = computePeriodDeltas(historicalStep.observations, timeRange); + const prevStats = periodCmp.previousStats; + const costCmp = isDwellBrief + ? computeCostComparison( + historicalStep.monthly, + historicalStep.cost?.unit_price, + waccRate, + storageCost, + timeRange, + ) + : null; + const minTrend = makeTrendChip( + periodCmp.statDeltas.min, + prevStats + ? `${formatNumber(prevStats.min, { maximumFractionDigits: 1 })}d` + : null, + ); + const medianTrend = makeTrendChip( + periodCmp.statDeltas.median, + prevStats + ? `${formatNumber(prevStats.median, { maximumFractionDigits: 1 })}d` + : null, + ); + const p95Trend = makeTrendChip( + periodCmp.statDeltas.p95, + prevStats + ? `${formatNumber(prevStats.p95, { maximumFractionDigits: 1 })}d` + : null, + ); + const maxTrend = makeTrendChip( + periodCmp.statDeltas.max, + prevStats + ? `${formatNumber(prevStats.max, { maximumFractionDigits: 1 })}d` + : null, + ); + const costTrend = + isDwellBrief && costCmp + ? makeTrendChip( + costCmp.delta, + costCmp.previousTotal != null + ? formatCost(costCmp.previousTotal, brief.currency, { + compact: true, + }) + : null, + ) + : undefined; + const backHrefSearchParams = new URLSearchParams(); + const range = searchParams.get("range"); + if (range) { + backHrefSearchParams.set("range", range); + } + const backHrefQuery = backHrefSearchParams.toString(); + const siteOverviewHref = `/supply-chain/site/${siteId}${ + backHrefQuery ? `?${backHrefQuery}` : "" + }`; + + return ( +
+ +
+
+
+ + openDocs("opportunity-brief")} + /> + + {evidence && evidence.rows.length > 0 && ( + + )} + +
+
+ +
+
+ Opportunity Brief + + + {isDwellBrief + ? "Dwell cost reduction" + : "Planning parameter calibration"} + + + {timeRangeLongLabel(timeRange)} +
+

{filteredStep.label}

+
+
+ + + +
+ product.name).join(", ")} + /> +
+
+ + + +
+ + + + + + + + + + + +
+ + + + {isDwellBrief ? ( + + ) : ( + + )} + + + + + + + + {isDwellBrief ? ( + + ) : ( + + )} + + {isDwellBrief && } + + {isDwellBrief && } + + {isDwellBrief && brief.firstUseDwell && ( + + )} + + {brief.supplier && } + + {brief.productionInsight && ( + + )} + + +
+ + + month.median ?? month.mean) + .filter((value): value is number => value != null)} + /> +
+
+ + + + ) : ( + "-" + ), + ], + ]} + /> + +
+

Evidence quality

+ {isDwellBrief && brief.distributionInsight && ( +

{brief.distributionInsight}

+ )} + {brief.clustering && ( +

{brief.clustering}

+ )} + {brief.evidenceFlags.length > 0 ? ( +
+ {brief.evidenceFlags.map((flag) => ( +
+
+ {flag.label} +
+

{flag.detail}

+
+ ))} +
+ ) : ( +

+ No major evidence caveats were detected for this period. +

+ )} +
+
+ + {brief.provenance && ( +

Source: {brief.provenance}

+ )} + {brief.normalizationNote && ( +

{brief.normalizationNote}

+ )} +
+ + + + + + + + + +
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/brief-charts.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/brief-charts.tsx new file mode 100644 index 00000000000..bbf53837ee6 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/brief-charts.tsx @@ -0,0 +1,372 @@ +import { useMemo } from "react"; + +import { css } from "@hashintel/ds-helpers/css"; + +import { chartTheme } from "../../shared/chart-theme"; +import { formatNumber } from "../../shared/cost"; + +import type { StepStats } from "../../shared/types"; + +/** + * Lightweight, print-friendly SVG/div charts for the opportunity brief. Kept + * separate from the recharts-based slideover charts so the brief renders crisply + * on paper (no responsive container, strokes stay 1px via non-scaling-stroke). + */ + +const chartWrap = css({ display: "flex", flexDirection: "column", gap: "1.5" }); +const chartTitle = css({ + textStyle: "xs", + fontWeight: "semibold", + textTransform: "uppercase", + letterSpacing: "[0.08em]", + color: "fg.muted", +}); +const axisRow = css({ + display: "flex", + justifyContent: "space-between", + textStyle: "xs", + color: "fg.subtle", + fontVariantNumeric: "tabular-nums", +}); +const boxSvg = css({ width: "full", height: "[56px]" }); +const sparkSvg = css({ width: "full", height: "[40px]" }); +const histRow = css({ + display: "flex", + alignItems: "flex-end", + gap: "[1px]", + h: "[64px]", +}); +const histBarCell = css({ + flex: "1", + h: "full", + display: "flex", + alignItems: "flex-end", +}); +const histBar = css({ + w: "full", + minH: "[1px]", + borderTopRadius: "sm", + bg: "status.info.bg.solid", +}); +const legendRow = css({ + display: "flex", + flexWrap: "wrap", + gap: "3", + textStyle: "xs", + color: "fg.muted", +}); +const legendItem = css({ + display: "inline-flex", + alignItems: "center", + gap: "1.5", +}); +const legendSwatch = css({ + display: "inline-block", + h: "2", + w: "2", + borderRadius: "full", +}); + +function scale(value: number, min: number, max: number): number { + if (max <= min) { + return 0; + } + return ((value - min) / (max - min)) * 100; +} + +/** Horizontal box plot: whiskers min..max, box P25-P75, median, P95 and an + * optional plan reference. Coordinates are percentages on a non-uniform SVG. */ +export const BriefBoxPlot = ({ + stats, + plan, +}: { + stats: StepStats; + plan?: number | null; +}) => { + const { min, max, p25, p75, median, p95 } = stats; + if ( + min == null || + max == null || + p25 == null || + p75 == null || + median == null || + max <= min + ) { + return null; + } + const xValue = (value: number) => scale(value, min, max); + const planIn = plan != null && plan >= min && plan <= max; + const boxWidth = Math.max(0, xValue(p75) - xValue(p25)); + return ( +
+ Distribution (box plot) + + + + + + + + + + + + + + {p95 != null && ( + + )} + {planIn && ( + + )} + +
+ min {formatNumber(min, { maximumFractionDigits: 1 })}d + + median {formatNumber(median, { maximumFractionDigits: 1 })}d + + max {formatNumber(max, { maximumFractionDigits: 1 })}d +
+
+ + + Median / IQR + + + + P95 + + {planIn && ( + + + Plan + + )} +
+
+ ); +}; + +interface SimpleBin { + label: string; + start: number; + end: number; + count: number; +} + +function buildSimpleBins(values: number[]): SimpleBin[] { + const clean = values.filter((value) => Number.isFinite(value)); + if (clean.length === 0) { + return []; + } + const min = Math.min(...clean); + const max = Math.max(...clean); + if (max <= min) { + return [ + { + label: `${formatNumber(min, { maximumFractionDigits: 1 })}`, + start: min, + end: max, + count: clean.length, + }, + ]; + } + const count = Math.min(Math.max(Math.ceil(Math.sqrt(clean.length)), 6), 16); + const step = (max - min) / count; + const bins: SimpleBin[] = []; + for (let index = 0; index < count; index++) { + const start = min + index * step; + const end = start + step; + const isLast = index === count - 1; + const column = clean.filter( + (value) => value >= start && (isLast ? value <= end : value < end), + ).length; + bins.push({ + label: `${formatNumber(start, { maximumFractionDigits: 1 })}-${formatNumber(end, { maximumFractionDigits: 1 })}`, + start, + end, + count: column, + }); + } + return bins; +} + +/** Compact histogram of observed values as flex bars. */ +export const BriefHistogram = ({ values }: { values: number[] }) => { + const bins = useMemo(() => buildSimpleBins(values), [values]); + if (bins.length === 0) { + return null; + } + const maxCount = Math.max(...bins.map((right) => right.count), 1); + const firstBin = bins[0]; + const lastBin = bins[bins.length - 1]; + if (!firstBin || !lastBin) { + return null; + } + + return ( +
+ Histogram +
+ {bins.map((bin) => ( +
+
+
+ ))} +
+
+ + {formatNumber(firstBin.start, { maximumFractionDigits: 1 })}d + + + {formatNumber(lastBin.end, { + maximumFractionDigits: 1, + })} + d + +
+
+ ); +}; + +/** Monthly trend sparkline (e.g. median by month). */ +export const BriefSparkline = ({ + points, + label, +}: { + points: number[]; + label: string; +}) => { + if (points.length < 2) { + return null; + } + const min = Math.min(...points); + const max = Math.max(...points); + const range = max - min || 1; + const coords = points + .map( + (product, index) => + `${(index / (points.length - 1)) * 100},${100 - ((product - min) / range) * 100}`, + ) + .join(" "); + return ( +
+ {label} + + + +
+ {formatNumber(points[0], { maximumFractionDigits: 1 })}d + + {formatNumber(points[points.length - 1], { + maximumFractionDigits: 1, + })} + d + +
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.test.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.test.ts new file mode 100644 index 00000000000..5c1706777b4 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.test.ts @@ -0,0 +1,455 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { + buildDwellOpportunityBrief, + buildPlanningOpportunityBrief, + computeTrend, +} from "./opportunity-utils"; + +import type { + DetailRows, + Observation, + SiteNode, + StepDetail, + StepStats, +} from "../../shared/types"; + +const baseStats: StepStats = { + n: 20, + mean: 12, + median: 10, + std: 2, + min: 5, + max: 25, + p25: 8, + p75: 14, + p85: 18, + p95: 22, +}; + +function step(overrides: Partial): StepDetail { + return { + id: "step-1", + label: "Step 1", + type: "production", + durations: [8, 10, 12], + observations: [ + { date: "2025-08-01", value: 9 }, + { date: "2026-02-01", value: 12 }, + ], + + monthly: [ + { month: "2026-01", mean: null, median: null, n: 2, total_kg_days: 1000 }, + ], + + stats: baseStats, + plan: 12, + plan_note: null, + pct_exceeding_plan: 35, + cost: { unit_price: 100, currency: "EUR" }, + ...overrides, + }; +} + +describe("opportunity brief helpers", () => { + it("adds trigger, confidence, and evidence guidance to dwell briefs", () => { + const brief = buildDwellOpportunityBrief( + step({ type: "qa_hold" }), + step({ type: "qa_hold" }), + "12m", + { + waccRate: 0.1, + storageCost: 0.336, + }, + ); + + expect(brief.opportunityTrigger.label).toBe("High dwell cost"); + expect(brief.opportunityTrigger.reason).toContain("carry cost"); + expect(brief.confidence.label).toBe("Limited"); + expect(brief.guidance.firstEvidence[0]).toContain("longest release delays"); + expect( + brief.evidenceFlags.some((flag) => flag.label === "Wide distribution"), + ).toBe(false); + expect(brief.distributionInsight).toContain("P95 dwell is"); + }); + + it("builds ordered dwell cap scenarios from observed dwell values", () => { + const brief = buildDwellOpportunityBrief( + step({ + stats: { ...baseStats, mean: 14, median: 10, p25: 8, p95: 22 }, + observations: [ + { date: "2026-01-01", value: 6 }, + { date: "2026-01-02", value: 10 }, + { date: "2026-01-03", value: 20 }, + { date: "2026-01-04", value: 30 }, + ], + }), + step({ observations: [] }), + "12m", + { waccRate: 0.1, storageCost: 0.336 }, + ); + + expect(brief.scenarios.map((scenario) => scenario.label)).toEqual([ + "Moderate", + "Stretch", + ]); + const moderateScenario = brief.scenarios[0]; + const stretchScenario = brief.scenarios[1]; + expect(moderateScenario).toBeDefined(); + expect(stretchScenario).toBeDefined(); + expect(moderateScenario!.targetDays).toBe(10); + expect(stretchScenario!.targetDays).toBe(8); + expect(stretchScenario!.reductionPct).toBeGreaterThanOrEqual( + moderateScenario!.reductionPct, + ); + expect(brief.scenarios.every((scenario) => !scenario.approximate)).toBe( + true, + ); + }); + + it("foregrounds planning distribution metrics versus plan", () => { + const brief = buildPlanningOpportunityBrief( + step({ + plan: 10, + stats: { ...baseStats, mean: 11, median: 8, p95: 15 }, + pct_exceeding_plan: 35, + }), + step({ + plan: 10, + stats: { ...baseStats, mean: 11, median: 8, p95: 15 }, + pct_exceeding_plan: 35, + }), + "12m", + "planning_over", + ); + + expect(brief.p95Days).toBe(15); + expect(brief.medianDays).toBe(8); + expect(brief.meanDays).toBe(11); + expect(brief.medianDeviationPct).toBeCloseTo(-20, 6); + expect(brief.meanDeviationPct).toBeCloseTo(10, 6); + expect(brief.p95DeviationPct).toBeCloseTo(50, 6); + expect(brief.nExceedingPlan).toBe(7); + expect(brief.calibrationDirection).toBe("increase"); + expect(brief.opportunityTrigger.primaryMetric).toContain("+50%"); + expect(brief.diagnosis[0]).toContain("below the observed high-percentile"); + }); + + it("labels conservative planning candidates as tighten opportunities", () => { + const brief = buildPlanningOpportunityBrief( + step({ plan: 20, stats: { ...baseStats, median: 8, p95: 14 } }), + step({ plan: 20, stats: { ...baseStats, median: 8, p95: 14 } }), + "12m", + ); + + expect(brief.p95DeviationPct).toBeCloseTo(-30, 6); + expect(brief.calibrationDirection).toBe("tighten"); + expect(brief.opportunityTrigger.label).toBe( + "Conservative planning parameter", + ); + }); +}); + +function detailRows( + keys: string[], + rows: Record[], +): DetailRows { + return { + columns: keys.map((key) => ({ + key, + source_field: null, + source_table: null, + label: key, + })), + rows, + }; +} + +describe("dwell detail-row analytics", () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-06-15T00:00:00Z")); + }); + afterEach(() => vi.useRealTimers()); + + it("derives receipt->first-consumption dwell per batch for lot-based dwell stages", () => { + const rows = [ + { + batch: "A", + consumption_date: "2026-01-10", + dwell_days: 5, + kg_days: 100, + }, + { + batch: "A", + consumption_date: "2026-02-10", + dwell_days: 35, + kg_days: 700, + }, + { + batch: "B", + consumption_date: "2026-01-15", + dwell_days: 8, + kg_days: 160, + }, + { + batch: "B", + consumption_date: "2026-03-15", + dwell_days: 60, + kg_days: 1200, + }, + { + batch: "C", + consumption_date: "2026-01-20", + dwell_days: 11, + kg_days: 220, + }, + { + batch: "D", + consumption_date: "2026-02-01", + dwell_days: 6, + kg_days: 120, + }, + { + batch: "D", + consumption_date: "2026-02-20", + dwell_days: 20, + kg_days: 400, + }, + ]; + + const step2 = step({ + type: "raw_material_dwell", + stats: { ...baseStats, median: 15 }, + detail_rows: detailRows( + ["batch", "consumption_date", "dwell_days", "kg_days"], + rows, + ), + }); + const brief = buildDwellOpportunityBrief(step2, step2, "12m", { + waccRate: 0.1, + storageCost: 0.336, + }); + const fu = brief.firstUseDwell; + expect(fu).not.toBeNull(); + // First draw per batch: A=5, B=8, C=11, D=6 (later tranches ignored). + expect(fu?.nBatches).toBe(4); + expect(fu?.medianDays).toBe(7); + expect(fu?.meanDays).toBe(7.5); + expect(fu?.overallMedianDays).toBe(15); + expect(fu?.structuralDays).toBe(8); + expect(fu?.firstUseSharePct).toBeCloseTo(46.67, 1); + expect(fu?.note).toContain("depletion"); + }); + + it("flags ordering-too-early when first-use dominates dwell", () => { + const rows = [ + { batch: "A", consumption_date: "2026-01-10", dwell_days: 9 }, + { batch: "B", consumption_date: "2026-01-15", dwell_days: 10 }, + { batch: "C", consumption_date: "2026-01-20", dwell_days: 11 }, + ]; + + const step2 = step({ + type: "raw_material_dwell", + stats: { ...baseStats, median: 11 }, + detail_rows: detailRows( + ["batch", "consumption_date", "dwell_days"], + rows, + ), + }); + const brief = buildDwellOpportunityBrief(step2, step2, "12m", { + waccRate: 0.1, + storageCost: 0.336, + }); + expect(brief.firstUseDwell?.firstUseSharePct).toBeGreaterThanOrEqual(60); + expect(brief.firstUseDwell?.note).toContain("ahead of first need"); + }); + + it("uses the true first draw but windows on the first-use date", () => { + // Batch A is first consumed in 2024 (before the 12m window) -> excluded + // entirely; its in-window 2026 tranche must NOT be counted as a 40d first use. + const rows = [ + { batch: "A", consumption_date: "2024-01-10", dwell_days: 3 }, + { batch: "A", consumption_date: "2026-02-10", dwell_days: 40 }, + { batch: "B", consumption_date: "2026-01-15", dwell_days: 8 }, + { batch: "C", consumption_date: "2026-01-20", dwell_days: 12 }, + { batch: "D", consumption_date: "2026-01-25", dwell_days: 10 }, + ]; + + const step2 = step({ + type: "raw_material_dwell", + stats: { ...baseStats, median: 15 }, + detail_rows: detailRows( + ["batch", "consumption_date", "dwell_days"], + rows, + ), + }); + const brief = buildDwellOpportunityBrief(step2, step2, "12m", { + waccRate: 0.1, + storageCost: 0.336, + }); + expect(brief.firstUseDwell?.nBatches).toBe(3); + expect(brief.firstUseDwell?.p95Days).toBeLessThan(40); + }); + + it("returns null first-use for non-tranche dwell stages", () => { + const step2 = step({ + type: "post_qa_ship", + detail_rows: detailRows( + ["batch", "consumption_date", "dwell_days"], + [ + { batch: "A", consumption_date: "2026-01-10", dwell_days: 5 }, + { batch: "B", consumption_date: "2026-01-11", dwell_days: 6 }, + { batch: "C", consumption_date: "2026-01-12", dwell_days: 7 }, + ], + ), + }); + expect( + buildDwellOpportunityBrief(step2, step2, "12m", { + waccRate: 0.1, + storageCost: 0.336, + }).firstUseDwell, + ).toBeNull(); + }); + + it("splits dwell impact by consuming material", () => { + const rows = [ + { + batch: "A", + consumption_date: "2026-01-10", + dwell_days: 5, + kg_days: 100, + cons_matnr: "M1", + cons_material_name: "Mat One", + }, + { + batch: "B", + consumption_date: "2026-01-11", + dwell_days: 6, + kg_days: 300, + cons_matnr: "M2", + cons_material_name: "Mat Two", + }, + { + batch: "C", + consumption_date: "2026-01-12", + dwell_days: 7, + kg_days: 100, + cons_matnr: "M1", + cons_material_name: "Mat One", + }, + ]; + + const step2 = step({ + type: "raw_material_dwell", + detail_rows: detailRows( + [ + "batch", + "consumption_date", + "dwell_days", + "kg_days", + "cons_matnr", + "cons_material_name", + ], + + rows, + ), + }); + const brief = buildDwellOpportunityBrief(step2, step2, "12m", { + waccRate: 0.1, + storageCost: 0.336, + }); + expect(brief.perProductImpact).toHaveLength(2); + const topImpact = brief.perProductImpact[0]; + expect(topImpact).toBeDefined(); + expect(topImpact!.label).toBe("Mat Two"); + expect(topImpact!.kgDays).toBe(300); + expect(topImpact!.sharePct).toBeCloseTo(60, 6); + }); +}); + +describe("end-to-end leverage and planning calibration", () => { + it("summarises end-to-end leverage from the node binding score", () => { + const siteNode = { + binding: { + all: { + binding_share: 0.4, + mean_slack: null, + next_bottleneck_days: 3, + expected_marginal_per_day: 0.15, + next_bottleneck_chains: [ + { label: "Production", step_id: "prod", share: 0.5 }, + ], + }, + }, + } as unknown as SiteNode; + const step2 = step({ type: "raw_material_dwell" }); + const brief = buildDwellOpportunityBrief( + step2, + step2, + "12m", + { waccRate: 0.1, storageCost: 0.336 }, + { siteNode }, + ); + expect(brief.e2eLeverage?.bindingSharePct).toBeCloseTo(40, 6); + expect(brief.e2eLeverage?.expectedMarginalPerDay).toBeCloseTo(0.15, 6); + expect(brief.e2eLeverage?.nextBottleneckDays).toBe(3); + expect(brief.e2eLeverage?.nextBottleneckLabel).toBe("Production"); + }); + + it("quantifies calibration buffer and residual late-event risk", () => { + const step2 = step({ + type: "procurement", + plan: 20, + durations: [5, 10, 15, 25], + stats: { ...baseStats, median: 10, p75: 15, p85: 18, p95: 22 }, + }); + const brief = buildPlanningOpportunityBrief(step2, step2, "12m"); + const p95 = brief.calibrationImpact.find((row) => row.label === "P95"); + expect(p95?.days).toBe(22); + expect(p95?.bufferDaysVsPlan).toBeCloseTo(-2, 6); + expect(p95?.pctExceeding).toBeCloseTo(25, 6); + const median = brief.calibrationImpact.find( + (row) => row.label === "Median", + ); + expect(median?.bufferDaysVsPlan).toBeCloseTo(10, 6); + expect(median?.pctExceeding).toBeCloseTo(50, 6); + }); +}); + +function obs(month: string, value: number): Observation { + return { date: `${month}-15`, value }; +} + +describe("computeTrend", () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-06-15T00:00:00Z")); + }); + afterEach(() => vi.useRealTimers()); + + it("compares current vs previous period medians (3m window)", () => { + // now=2026-06 -> current >= 2026-04; previous = 2026-01..2026-03 + const observations: Observation[] = [ + obs("2025-12", 30), + obs("2026-01", 50), + obs("2026-03", 10), + obs("2026-04", 20), + ]; + + const trend = computeTrend(observations, "3m"); + expect(trend.currentValue).toBe(20); + expect(trend.previousValue).toBe(30); + expect(trend.currentN).toBe(1); + expect(trend.previousN).toBe(2); + expect(trend.pctChange).toBeCloseTo(-33.333333, 6); + expect(trend.direction).toBe("improving"); + }); + + it("reports unknown direction when a period has no data", () => { + const trend = computeTrend([obs("2026-04", 20)], "3m"); + expect(trend.previousN).toBe(0); + expect(trend.pctChange).toBeNull(); + expect(trend.direction).toBe("unknown"); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.ts new file mode 100644 index 00000000000..56e7d9fc82a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/opportunity-utils.ts @@ -0,0 +1,1552 @@ +import { + computeMonthlyCost, + computePeriodCost, + costRatePerKgDay, + formatNumber, +} from "../../shared/cost"; +import { computeTrend, computePeriodDeltas } from "../../shared/period-trends"; +import { percentileOf } from "../../shared/stats"; +import { recomputeSupplierBlock } from "../../shared/supplier-otif"; +import { + type TimeRange, + cutoffForRange, + rangeMonths, +} from "../../shared/time-range"; + +import type { + BindingScore, + GraphNode, + MonthlyBucket, + Observation, + SiteNode, + StepDetail, + StepStats, + StepType, +} from "../../shared/types"; + +export { computeTrend }; +import { + PLAYBOOKS, + diagnosisFor, + firstEvidenceFor, + shapeSignals, + type NextStepsChecklist, + type PlaybookContext, +} from "./recommendation-playbook"; + +export type OpportunityType = "dwell" | "planning"; +export type OpportunityBriefSourceKind = + | "dwell_cost" + | "planning_over" + | "planning_under" + | null; + +export interface CostAssumptions { + waccRate: number; + storageCost: number; +} + +/** A single product's own (pre-dedup) graph node for the brief's step/material. */ +export interface ProductNodeRef { + productId: string; + productName: string; + node: GraphNode; +} + +/** + * Extra context for the dwell brief that the deduped step detail cannot carry: + * the resolved site node (for E2E binding leverage) and every consuming + * product's own node (for per-product BOM membership). Both are optional so the + * builder still works from step detail alone (e.g. in unit tests). + */ +export interface DwellBriefContext { + siteNode?: SiteNode | null; + productNodes?: ProductNodeRef[]; +} + +export interface OpportunityTrend { + pctChange: number | null; + currentValue: number | null; + previousValue: number | null; + currentN: number; + previousN: number; + direction: "improving" | "worsening" | "flat" | "unknown"; +} + +export interface EvidenceFlag { + severity: "info" | "warning"; + label: string; + detail: string; +} + +export interface OpportunityTrigger { + label: string; + reason: string; + primaryMetric: string; +} + +export interface OpportunityConfidence { + label: "High" | "Limited" | "Low"; + caveats: string[]; + explanation: string; +} + +export interface OpportunityBriefGuidance { + firstEvidence: string[]; +} + +/** End-to-end leverage of reducing this step, from the node's binding score. */ +export interface E2ELeverage { + bindingSharePct: number; + expectedMarginalPerDay: number; + nextBottleneckDays: number | null; + nextBottleneckLabel: string | null; +} + +/** Per-consuming-material breakdown of a shared material's dwell impact. */ +export interface PerProductImpactRow { + key: string; + label: string; + kgDays: number; + periodCost: number | null; + sharePct: number; + events: number; + /** + * Whether this consuming material still lists the step material in its current + * BOM. False => off-recipe (badge it); null => no current BOM extract to judge. + */ + inCurrentRecipe: boolean | null; +} + +/** Whether a consuming product still uses this material in its current recipe. */ +export interface RecipeMembership { + productName: string; + inCurrentRecipe: boolean | null; +} + +/** A single high-leverage evidence row surfaced inline in the brief. */ +export interface BriefEvidenceRow { + label: string; + date: string | null; + days: number | null; + kgDays: number | null; +} + +/** Compact per-vendor OTIF line for the procurement brief. */ +export interface SupplierBriefVendor { + name: string; + otifPct: number | null; + meanDaysLateAll: number | null; + ge7dPct: number | null; + nLines: number; +} + +/** Materialised supplier OTIF subset rendered in procurement briefs. */ +export interface SupplierBriefSummary { + primaryVendorName: string | null; + vendors: SupplierBriefVendor[]; + worstEvents: Array<{ + vendorName: string | null; + materialName: string | null; + poNumber: string | null; + daysLate: number; + date: string | null; + }>; + nLines: number; + coveragePct: number | null; + dataQualityNote: string | null; +} + +/** Plain-language yield / consumption notes for production steps. */ +export interface ProductionInsight { + yield: string | null; + consumption: string | null; +} + +/** + * Receipt -> first-consumption dwell for lot-based dwell stages (raw material + * and intermediate). The first draw off each received batch isolates the + * avoidable "ordered too early" wait from the structural depletion tail (later + * tranches that are inevitable once you buy in lots), so a large first-use dwell + * is a clean signal that ordering/scheduling runs ahead of first need. + */ +export interface FirstUseDwellSummary { + medianDays: number; + p95Days: number; + meanDays: number; + nBatches: number; + /** Event-level median dwell across all consumption events, for comparison. */ + overallMedianDays: number | null; + /** Structural depletion portion (overall median - first-use median), >= 0. */ + structuralDays: number | null; + /** First-use dwell as a share of overall median dwell (%). */ + firstUseSharePct: number | null; + note: string; +} + +export interface DwellScenario { + label: string; + targetDays: number; + reductionPct: number; + periodSaving: number | null; + annualizedSaving: number | null; + reducedPeriodCost: number | null; + rationale: string; + approximate: boolean; +} + +export interface DwellOpportunityBrief { + kind: "dwell"; + stepType: StepType; + opportunityTrigger: OpportunityTrigger; + confidence: OpportunityConfidence; + guidance: OpportunityBriefGuidance; + periodCost: number | null; + annualizedCost: number | null; + currency: string | null; + scenarios: DwellScenario[]; + diagnosis: string[]; + evidenceFlags: EvidenceFlag[]; + trend: OpportunityTrend; + distributionInsight: string | null; + highestCostMonth: { month: string; cost: number; events: number } | null; + recommendationSummary: string; + nextSteps: NextStepsChecklist; + e2eLeverage: E2ELeverage | null; + perProductImpact: PerProductImpactRow[]; + recipeMembership: RecipeMembership[]; + outOfCurrentRecipe: boolean; + supplier: SupplierBriefSummary | null; + topEvidence: BriefEvidenceRow[]; + provenance: string | null; + normalizationNote: string | null; + productionInsight: ProductionInsight | null; + clustering: string | null; + tailTrendNote: string | null; + firstUseDwell: FirstUseDwellSummary | null; +} + +export interface PlanningCalibrationImpact { + label: string; + days: number | null; + bufferDaysVsPlan: number | null; + pctExceeding: number | null; + description: string; +} + +export interface PlanningOpportunityBrief { + kind: "planning"; + stepType: StepType; + opportunityTrigger: OpportunityTrigger; + confidence: OpportunityConfidence; + guidance: OpportunityBriefGuidance; + currentPlanDays: number | null; + p95Days: number | null; + medianDays: number | null; + meanDays: number | null; + serviceLevelOptions: Array<{ + label: string; + days: number | null; + description: string; + }>; + medianDeviationPct: number | null; + meanDeviationPct: number | null; + p95DeviationPct: number | null; + pctExceedingPlan: number | null; + nExceedingPlan: number | null; + calibrationDirection: "increase" | "tighten" | "review"; + calibrationImpact: PlanningCalibrationImpact[]; + diagnosis: string[]; + evidenceFlags: EvidenceFlag[]; + trend: OpportunityTrend; + recommendationSummary: string; + nextSteps: NextStepsChecklist; + supplier: SupplierBriefSummary | null; + topEvidence: BriefEvidenceRow[]; + provenance: string | null; + normalizationNote: string | null; + productionInsight: ProductionInsight | null; + clustering: string | null; + tailTrendNote: string | null; +} + +const LOW_SAMPLE_N = 10; +const STALE_OBSERVATION_DAYS = 60; + +export function buildOpportunityBackLink( + siteId: string, + search: URLSearchParams | null = null, + fallback = "/supply-chain", +): string { + const path = siteId ? `/supply-chain/site/${siteId}` : fallback; + if (!search) { + return path; + } + const carry = new URLSearchParams(); + const cat = search.get("cat"); + if (cat) { + carry.set("cat", cat); + } + const range = search.get("range"); + if (range) { + carry.set("range", range); + } + const query = carry.toString(); + return query ? `${path}?${query}` : path; +} + +export function firstProductForNode( + node: SiteNode, + requestedProductId?: string, +): string { + if ( + requestedProductId && + node.products.some((product) => product.id === requestedProductId) + ) { + return requestedProductId; + } + return node.products[0]?.id ?? requestedProductId ?? ""; +} + +function positiveOrZero(value: number | null | undefined): number { + return value == null ? 0 : Math.max(0, value); +} + +function cappedReductionPct( + observations: Observation[], + capDays: number, + stats: StepStats, +): number { + const values = observations + .map((observation) => observation.value) + .filter((value) => value > 0); + if (values.length > 0) { + const total = values.reduce((sum, value) => sum + value, 0); + if (total <= 0) { + return 0; + } + const removable = values.reduce( + (sum, value) => sum + Math.max(0, value - capDays), + 0, + ); + return Math.max(0, Math.min(1, removable / total)); + } + const mean = positiveOrZero(stats.mean); + if (mean <= 0) { + return 0; + } + return Math.max(0, Math.min(1, (mean - capDays) / mean)); +} + +function round1(value: number): number { + return Math.round(value * 10) / 10; +} + +function formatSignedPct(value: number | null): string { + if (value == null) { + return "–"; + } + return `${value > 0 ? "+" : ""}${formatNumber(value, { maximumFractionDigits: 0 })}%`; +} + +function trendDiagnosis( + trend: OpportunityTrend, + range: TimeRange, + p95Over: boolean, + p95Under: boolean, +): string { + if ( + trend.pctChange == null || + trend.currentValue == null || + trend.previousValue == null + ) { + return `No comparable previous-period trend is available for the ${range} window.`; + } + const direction = + trend.pctChange > 0 + ? "worsening" + : trend.pctChange < 0 + ? "improving" + : "flat"; + const comparison = `${formatNumber(trend.currentValue, { maximumFractionDigits: 1 })} days currently vs ${formatNumber(trend.previousValue, { maximumFractionDigits: 1 })} days in the previous comparable ${range} window (${formatSignedPct(trend.pctChange)})`; + if (direction === "improving" && p95Over) { + return `Trend is improving (${comparison}), but the current high-percentile lead time is still above plan; confirm the gain is structural before choosing how far to increase the planning parameter.`; + } + if (direction === "worsening" && p95Under) { + return `Trend is worsening (${comparison}), so treat the apparent conservative planning buffer cautiously before tightening it.`; + } + if (direction === "improving") { + return `Trend is improving (${comparison}); validate whether the improvement is structural before locking in tighter assumptions.`; + } + if (direction === "worsening") { + return `Trend is worsening (${comparison}); the current parameter may need more protection if the change persists.`; + } + return `Trend is broadly flat (${comparison}); use the distribution statistics as the main calibration signal.`; +} + +function latestObservationDate(observations: Observation[]): Date | null { + if (observations.length === 0) { + return null; + } + return ( + observations + .map((observation) => new Date(observation.date)) + .filter((date) => !Number.isNaN(date.getTime())) + .sort((left, right) => right.getTime() - left.getTime())[0] ?? null + ); +} + +function formatCostForText( + value: number | null, + currency: string | null, +): string { + if (value == null) { + return "unknown"; + } + return `${currency ? `${currency} ` : ""}${formatNumber(value, { compact: true, maximumFractionDigits: 1 })}`; +} + +function toNumber(value: string | number | null | undefined): number { + if (typeof value === "number") { + return Number.isFinite(value) ? value : 0; + } + const count = Number(value); + return Number.isFinite(count) ? count : 0; +} + +function toNumberOrNull( + value: string | number | null | undefined, +): number | null { + if (value == null || value === "") { + return null; + } + const count = typeof value === "number" ? value : Number(value); + return Number.isFinite(count) ? count : null; +} + +function pickFirstKey(keys: Set, candidates: string[]): string | null { + for (const column of candidates) { + if (keys.has(column)) { + return column; + } + } + return null; +} + +function buildFirstUseNote( + medianDays: number, + overallMedianDays: number | null, + structuralDays: number | null, + firstUseSharePct: number | null, +): string { + const median = formatNumber(medianDays, { maximumFractionDigits: 1 }); + if ( + overallMedianDays == null || + structuralDays == null || + firstUseSharePct == null + ) { + return `The first draw off a received batch waits ${median}d on average before it is consumed.`; + } + const overall = formatNumber(overallMedianDays, { maximumFractionDigits: 1 }); + const structural = formatNumber(structuralDays, { maximumFractionDigits: 1 }); + const share = formatNumber(firstUseSharePct, { maximumFractionDigits: 0 }); + const lead = + firstUseSharePct >= 60 + ? `Most dwell is incurred before the lot is first touched: the first draw waits ${median}d (${share}% of the ${overall}d typical dwell), which points to ordering or scheduling consistently ahead of first need rather than to lot depletion.` + : `The first draw waits ${median}d (${share}% of the ${overall}d typical dwell); the remaining ~${structural}d reflects depletion of the received lot across later consumption events, which is harder to avoid with lot-based purchasing.`; + return `${lead} Pull the first-use wait down by ordering closer to first need, smaller/more frequent call-offs, or tighter delivery scheduling.`; +} + +/** Materialise a compact supplier-OTIF subset for procurement briefs. */ + +function pctExceedingValue(values: number[], threshold: number): number | null { + if (values.length === 0) { + return null; + } + return ( + (values.filter((value) => value > threshold).length / values.length) * 100 + ); +} + +function buildDwellScenarios( + step: StepDetail, + range: TimeRange, + periodCost: number | null, +): DwellScenario[] { + const medianValue = positiveOrZero(step.stats.median); + const p25Value = positiveOrZero(step.stats.p25); + if (medianValue <= 0) { + return []; + } + const stretchCap = + p25Value > 0 && p25Value <= medianValue ? p25Value : medianValue; + const months = rangeMonths(range); + + return [ + { + label: "Moderate", + targetDays: medianValue, + reductionPct: cappedReductionPct( + step.observations, + medianValue, + step.stats, + ), + rationale: `Caps observed dwell values above the current median (${formatNumber(medianValue, { maximumFractionDigits: 1 })}d) to the median.`, + }, + { + label: "Stretch", + targetDays: stretchCap, + reductionPct: cappedReductionPct( + step.observations, + stretchCap, + step.stats, + ), + rationale: `Caps observed dwell values above P25 (${formatNumber(stretchCap, { maximumFractionDigits: 1 })}d) to lower-quartile performance.`, + }, + ] + + .map((scenario) => { + const targetDays = round1(Math.max(0, scenario.targetDays)); + const periodSaving = + periodCost == null ? null : periodCost * scenario.reductionPct; + return { + ...scenario, + targetDays, + reductionPct: scenario.reductionPct, + periodSaving, + annualizedSaving: + periodSaving == null ? null : periodSaving * (12 / months), + reducedPeriodCost: + periodCost == null || periodSaving == null + ? null + : periodCost - periodSaving, + approximate: step.observations.length === 0, + }; + }) + .filter((scenario) => scenario.reductionPct > 0); +} + +function periodCostOrNull( + monthly: MonthlyBucket[] | undefined, + unitPrice: number | null | undefined, + assumptions: CostAssumptions, +): number | null { + const costMonths = + monthly?.filter((month) => month.total_kg_days != null) ?? []; + if (costMonths.length === 0 || unitPrice == null) { + return null; + } + return computePeriodCost( + costMonths, + unitPrice, + assumptions.waccRate, + assumptions.storageCost, + ); +} + +function computeHighestCostMonth( + monthly: MonthlyBucket[] | undefined, + unitPrice: number | null | undefined, + assumptions: CostAssumptions, +): { month: string; cost: number; events: number } | null { + const rows = + monthly + ?.map((month) => ({ + month: month.month, + cost: computeMonthlyCost( + month.total_kg_days, + unitPrice, + assumptions.waccRate, + assumptions.storageCost, + ), + events: month.n, + })) + .filter( + (month): month is { month: string; cost: number; events: number } => + month.cost != null, + ) ?? []; + if (rows.length === 0) { + return null; + } + return rows.sort((left, right) => right.cost - left.cost)[0] ?? null; +} + +function diagnoseTimingShape( + stepType: StepType, + stats: StepStats, + trend: OpportunityTrend, +): string[] { + const signals = shapeSignals(stats, trend); + const lines = diagnosisFor(stepType, signals); + if (lines.length > 0) { + return lines; + } + return [ + "The opportunity appears mixed: use the distribution, trend, and underlying rows to separate normal waiting from exceptions.", + ]; +} + +function buildPlanningDiagnosis( + step: StepDetail, + trend: OpportunityTrend, + range: TimeRange, + context: { + sourceKind: OpportunityBriefSourceKind; + p95DeviationPct: number | null; + medianDeviationPct: number | null; + meanDeviationPct: number | null; + confidence: OpportunityConfidence; + p95Days: number | null; + }, +): string[] { + const lines: string[] = []; + const p95Over = (context.p95DeviationPct ?? 0) > 0; + const p95Under = (context.p95DeviationPct ?? 0) < 0; + const p95Text = + context.p95Days == null + ? "P95 is unavailable" + : `P95 is ${formatNumber(context.p95Days, { maximumFractionDigits: 0 })} days (${formatSignedPct(context.p95DeviationPct)} vs plan)`; + const medianText = `median is ${formatNumber(step.stats.median, { maximumFractionDigits: 1 })} days (${formatSignedPct(context.medianDeviationPct)} vs plan)`; + const meanText = `mean is ${formatNumber(step.stats.mean, { maximumFractionDigits: 1 })} days (${formatSignedPct(context.meanDeviationPct)} vs plan)`; + + if ( + context.sourceKind === "planning_under" || + (p95Under && context.sourceKind !== "planning_over") + ) { + lines.push( + `The planning parameter appears conservative: ${p95Text}, while ${medianText} and ${meanText}. Validate service requirements before tightening the parameter.`, + ); + } else if (p95Over) { + lines.push( + `The planning parameter is below the observed high-percentile lead time: ${p95Text}, while ${medianText} and ${meanText}. Align the planning parameter only after validating whether recent performance is stable.`, + ); + } else { + lines.push( + `The planning parameter is close to observed high-percentile timing: ${p95Text}, while ${medianText} and ${meanText}. Review whether the current assumption still matches the intended service level.`, + ); + } + + lines.push(trendDiagnosis(trend, range, p95Over, p95Under)); + lines.push( + `Confidence is ${context.confidence.label.toLowerCase()}: ${context.confidence.explanation}`, + ); + return lines; +} + +function buildEvidenceFlags( + step: StepDetail, + options: { + needsCost: boolean; + hasUnitCost: boolean; + trend: OpportunityTrend; + }, +): EvidenceFlag[] { + const flags: EvidenceFlag[] = []; + if (step.stats.n > 0 && step.stats.n < LOW_SAMPLE_N) { + flags.push({ + severity: "warning", + label: "Low sample", + detail: `Only ${formatNumber(step.stats.n)} observations are in the selected period.`, + }); + } + if ((step.excluded_pct ?? 0) > 20) { + flags.push({ + severity: "warning", + label: "Outlier-sensitive", + detail: `${round1(step.excluded_pct ?? 0)}% of observations are excluded by the current outlier setting.`, + }); + } + if (options.needsCost && !options.hasUnitCost) { + flags.push({ + severity: "warning", + label: "Missing unit cost", + detail: + "Potential cost impact cannot be calculated without a material unit cost.", + }); + } + if (options.trend.previousN > 0 && options.trend.previousN < LOW_SAMPLE_N) { + flags.push({ + severity: "info", + label: "Trend sample", + detail: `Previous comparison period has ${formatNumber(options.trend.previousN)} observations.`, + }); + } + + const last = latestObservationDate(step.observations); + if (last) { + const ageDays = Math.floor( + (Date.now() - last.getTime()) / (1000 * 60 * 60 * 24), + ); + if (ageDays > STALE_OBSERVATION_DAYS) { + flags.push({ + severity: "info", + label: "Stale recent data", + detail: `Latest observation is ${ageDays} days old.`, + }); + } + } + return flags; +} + +function buildDwellDistributionInsight(step: StepDetail): string | null { + const median = step.stats.median; + const p95 = step.stats.p95; + if (median == null || p95 == null || median <= 0 || p95 <= median) { + return null; + } + const spread = p95 - median; + return `P95 dwell is ${formatNumber(p95, { maximumFractionDigits: 1 })}d vs ${formatNumber(median, { maximumFractionDigits: 1 })}d median, so the longest 5% of events are at least ${formatNumber(spread, { maximumFractionDigits: 1 })}d above the typical case.`; +} + +function buildDwellTrigger( + step: StepDetail, + periodCost: number | null, + range: TimeRange, +): OpportunityTrigger { + const median = step.stats.median; + const costText = formatCostForText(periodCost, step.cost?.currency ?? null); + return { + label: "High dwell cost", + primaryMetric: + periodCost == null + ? `${formatNumber(median, { maximumFractionDigits: 1 })}d median dwell` + : `${costText} carry cost`, + reason: + periodCost == null + ? `Qualified because observed median dwell is ${formatNumber(median, { maximumFractionDigits: 1 })} days in the selected period.` + : `Qualified because ${range} carry cost is ${costText} and observed median dwell is ${formatNumber(median, { maximumFractionDigits: 1 })} days.`, + }; +} + +function buildPlanningTrigger( + step: StepDetail, + p95DeviationPct: number | null, +): OpportunityTrigger { + const plan = step.plan; + const p95 = step.stats.p95; + const direction = + p95DeviationPct == null + ? "needs review" + : p95DeviationPct > 0 + ? "may not protect the observed service level" + : "may be conservative versus observed performance"; + return { + label: + p95DeviationPct != null && p95DeviationPct < 0 + ? "Conservative planning parameter" + : "Planning parameter divergence", + primaryMetric: + p95DeviationPct == null + ? "P95 vs plan unavailable" + : `${p95DeviationPct > 0 ? "+" : ""}${formatNumber(p95DeviationPct, { maximumFractionDigits: 0 })}% P95 vs plan`, + reason: + plan == null || p95 == null + ? "Qualified because the planning assumption should be reviewed once more observations are available." + : `Qualified because P95 is ${formatNumber(p95, { maximumFractionDigits: 1 })} days vs plan ${formatNumber(plan, { maximumFractionDigits: 1 })} days; the parameter ${direction}.`, + }; +} + +function buildConfidence( + step: StepDetail, + flags: EvidenceFlag[], +): OpportunityConfidence { + const caveats = flags.map((flag) => `${flag.label}: ${flag.detail}`); + const hasWarning = flags.some((flag) => flag.severity === "warning"); + if (step.stats.n < LOW_SAMPLE_N || hasWarning) { + return { + label: "Low", + caveats, + explanation: + caveats.length > 0 + ? caveats.join(" ") + : `Only ${formatNumber(step.stats.n)} observations are available in the selected period.`, + }; + } + if (step.stats.n < LOW_SAMPLE_N * 2 || flags.length > 0) { + return { + label: "Limited", + caveats, + explanation: + caveats.length > 0 + ? caveats.join(" ") + : `${formatNumber(step.stats.n)} observations are available; validate the underlying rows before changing planning assumptions.`, + }; + } + return { + label: "High", + caveats: [], + explanation: `${formatNumber(step.stats.n)} observations are available and no major evidence caveats were detected.`, + }; +} + +function buildGuidance(stepType: StepType): OpportunityBriefGuidance { + return { + firstEvidence: firstEvidenceFor(stepType), + }; +} + +/** Resolve the most representative binding score for a node (prefers "all"). */ +function resolveBindingScore( + node: SiteNode | null | undefined, +): BindingScore | null { + const binding = node?.binding; + if (!binding) { + return null; + } + if (binding.all) { + return binding.all; + } + const first = Object.values(binding)[0]; + return first ?? null; +} + +/** E2E leverage from the node's binding score: does reducing this step move the + * end-to-end lead time, and what becomes binding next. */ +function buildE2ELeverage( + node: SiteNode | null | undefined, +): E2ELeverage | null { + const score = resolveBindingScore(node); + if (!score) { + return null; + } + const nextChain = score.next_bottleneck_chains?.[0] ?? null; + return { + bindingSharePct: score.binding_share * 100, + expectedMarginalPerDay: score.expected_marginal_per_day, + nextBottleneckDays: score.next_bottleneck_days, + nextBottleneckLabel: nextChain?.label ?? null, + }; +} + +/** Per-product recipe membership from each consuming product's own node. */ +function buildRecipeMembership( + productNodes: ProductNodeRef[] | undefined, +): RecipeMembership[] { + if (!productNodes || productNodes.length === 0) { + return []; + } + return productNodes + .map((ref) => ({ + productName: ref.productName, + inCurrentRecipe: ref.node.in_current_recipe ?? null, + })) + .sort((left, right) => left.productName.localeCompare(right.productName)); +} + +/** True when the material is in no consuming product's current recipe. */ +function isOutOfCurrentRecipe( + node: SiteNode | null | undefined, + membership: RecipeMembership[], +): boolean { + if (membership.length > 0) { + return membership.every((month) => month.inCurrentRecipe === false); + } + return node?.in_current_recipe === false; +} + +/** Group the step's consumption detail rows by consuming produced material and + * re-apply the carrying-cost model to estimate impact per consuming product. */ +function computePerProductImpact( + step: StepDetail, + range: TimeRange, + assumptions: CostAssumptions, +): PerProductImpactRow[] { + const detail = step.detail_rows; + if (!detail) { + return []; + } + const keys = new Set(detail.columns.map((column) => column.key)); + if ( + !keys.has("kg_days") || + (!keys.has("cons_matnr") && !keys.has("cons_material_name")) + ) { + return []; + } + const cutoff = cutoffForRange(range); + const dateKey = keys.has("consumption_date") ? "consumption_date" : null; + const rate = costRatePerKgDay( + step.cost?.unit_price, + assumptions.waccRate, + assumptions.storageCost, + ); + const hasUnitCost = step.cost?.unit_price != null; + + const groups = new Map< + string, + { + label: string; + kgDays: number; + events: number; + recipeTrue: number; + recipeFalse: number; + } + >(); + for (const row of detail.rows) { + if (dateKey) { + const dv = row[dateKey]; + if (typeof dv === "string" && dv.slice(0, 7) < cutoff) { + continue; + } + } + const code = row.cons_matnr; + const name = row.cons_material_name; + const key = String(code ?? name ?? "unknown"); + const label = String(name ?? code ?? "Unknown"); + const kg = toNumber(row.kg_days); + const bucket = groups.get(key) ?? { + label, + kgDays: 0, + events: 0, + recipeTrue: 0, + recipeFalse: 0, + }; + bucket.kgDays += kg; + bucket.events += 1; + // Emitted as 1 (in current BOM) / 0 (off-recipe) / null (no BOM to judge). + const inRecipe = row.cons_in_current_recipe; + if (inRecipe === 1) { + bucket.recipeTrue += 1; + } else if (inRecipe === 0) { + bucket.recipeFalse += 1; + } + groups.set(key, bucket); + } + + const total = [...groups.values()].reduce( + (sum, group) => sum + group.kgDays, + 0, + ); + if (groups.size <= 1 || total <= 0) { + return []; + } + + return [...groups.entries()] + .map(([key, group]) => ({ + key, + label: group.label, + kgDays: group.kgDays, + periodCost: hasUnitCost ? group.kgDays * rate : null, + sharePct: total > 0 ? (group.kgDays / total) * 100 : 0, + events: group.events, + // Off-recipe only when we saw an explicit "not in current BOM" flag and + // never an in-recipe one; null when the consumer had no BOM to judge. + inCurrentRecipe: + group.recipeTrue > 0 ? true : group.recipeFalse > 0 ? false : null, + })) + .sort((left, right) => right.kgDays - left.kgDays); +} + +/** Dwell stages whose detail rows carry the receipt -> consumption tranche + * structure needed to recover the first draw off each received batch. */ +const FIRST_USE_DWELL_TYPES: ReadonlySet = new Set([ + "raw_material_dwell", + "intermediate_dwell", +]); +const MIN_FIRST_USE_BATCHES = 3; + +/** + * First-use dwell: per received batch, the dwell of its earliest consumption + * event (receipt -> first use). The first draw is found over all detail rows so + * pre-window tranches are not mistaken for the first use; batches are then kept + * when that first use falls inside the selected window. + */ +function buildFirstUseDwell( + step: StepDetail, + range: TimeRange, +): FirstUseDwellSummary | null { + if (!FIRST_USE_DWELL_TYPES.has(step.type)) { + return null; + } + const detail = step.detail_rows; + if (!detail) { + return null; + } + const keys = new Set(detail.columns.map((column) => column.key)); + if ( + !keys.has("batch") || + !keys.has("consumption_date") || + !keys.has("dwell_days") + ) { + return null; + } + + const firstByBatch = new Map(); + for (const row of detail.rows) { + const batch = row.batch; + const date = row.consumption_date; + const dwell = toNumberOrNull(row.dwell_days); + if ( + batch == null || + typeof date !== "string" || + dwell == null || + dwell < 0 + ) { + continue; + } + const key = String(batch); + const existing = firstByBatch.get(key); + if (!existing || date < existing.date) { + firstByBatch.set(key, { date, dwell }); + } + } + + const cutoff = cutoffForRange(range); + const values = [...firstByBatch.values()] + .filter((value) => value.date.slice(0, 7) >= cutoff) + .map((value) => value.dwell); + if (values.length < MIN_FIRST_USE_BATCHES) { + return null; + } + values.sort((left, right) => left - right); + + const medianDays = round1(percentileOf(values, 50)); + const p95Days = round1(percentileOf(values, 95)); + const meanDays = round1( + values.reduce((sum, value) => sum + value, 0) / values.length, + ); + const overallMedianDays = step.stats.median ?? null; + const structuralDays = + overallMedianDays != null + ? round1(Math.max(0, overallMedianDays - medianDays)) + : null; + const firstUseSharePct = + overallMedianDays != null && overallMedianDays > 0 + ? Math.min(100, (medianDays / overallMedianDays) * 100) + : null; + return { + medianDays, + p95Days, + meanDays, + nBatches: values.length, + overallMedianDays, + structuralDays, + firstUseSharePct, + note: buildFirstUseNote( + medianDays, + overallMedianDays, + structuralDays, + firstUseSharePct, + ), + }; +} + +function buildSupplierSummary( + step: StepDetail, + range: TimeRange, +): SupplierBriefSummary | null { + const block = step.supplier_otif; + if (!block) { + return null; + } + const materialised = recomputeSupplierBlock(block, range); + if (materialised.n_lines === 0) { + return null; + } + const vendors: SupplierBriefVendor[] = materialised.vendors + .map((value) => ({ + name: value.vendor_name ?? value.vendor_id ?? "Unknown vendor", + otifPct: value.otif_pct, + meanDaysLateAll: value.mean_days_late_all, + ge7dPct: value.late_buckets.ge_7d_pct ?? null, + nLines: value.n_lines, + })) + .sort( + (left, right) => + (right.meanDaysLateAll ?? Number.NEGATIVE_INFINITY) - + (left.meanDaysLateAll ?? Number.NEGATIVE_INFINITY), + ) + .slice(0, 3); + const worstEvents = (materialised.worst_events ?? []) + .slice(0, 5) + .map((event) => ({ + vendorName: event.vendor_name, + materialName: event.material_name, + poNumber: event.po_number, + daysLate: event.days_late, + date: event.first_gr_date ?? event.promised_date ?? null, + })); + return { + primaryVendorName: materialised.primary_vendor?.name ?? null, + vendors, + worstEvents, + nLines: materialised.n_lines, + coveragePct: materialised.coverage_pct, + dataQualityNote: materialised.data_quality_note, + }; +} + +/** Top evidence rows (longest, and largest kg-days for dwell) from detail rows. */ +function buildTopEvidence( + step: StepDetail, + range: TimeRange, +): BriefEvidenceRow[] { + const detail = step.detail_rows; + if (!detail) { + return []; + } + const keys = new Set(detail.columns.map((column) => column.key)); + const dateKey = pickFirstKey(keys, [ + "consumption_date", + "receipt_date", + "po_date", + "delivery_date", + "qa_release_date", + ]); + const daysKey = + pickFirstKey(keys, ["dwell_days", "duration", "days", "lead_time_days"]) ?? + step.value_col ?? + null; + const kgKey = keys.has("kg_days") ? "kg_days" : null; + const labelKey = pickFirstKey(keys, [ + "batch", + "po_number", + "cons_material_name", + "material", + ]); + const cutoff = cutoffForRange(range); + + const rows = detail.rows.filter((row) => { + if (!dateKey) { + return true; + } + const dv = row[dateKey]; + return typeof dv !== "string" || dv.slice(0, 7) >= cutoff; + }); + if (rows.length === 0) { + return []; + } + + const rankKey = kgKey ?? daysKey; + if (!rankKey) { + return []; + } + const ranked = [...rows] + .sort((left, right) => toNumber(right[rankKey]) - toNumber(left[rankKey])) + .slice(0, 5); + return ranked.map((row) => ({ + label: labelKey ? String(row[labelKey] ?? "–") : "–", + date: dateKey && typeof row[dateKey] === "string" ? row[dateKey] : null, + days: daysKey ? toNumberOrNull(row[daysKey]) : null, + kgDays: kgKey ? toNumberOrNull(row[kgKey]) : null, + })); +} + +/** Provenance label (source population + filter). */ +function buildProvenance(step: StepDetail): string | null { + const source = step.source; + if (!source?.label) { + return null; + } + const filter = source.filter ? ` (${source.filter})` : ""; + return `${source.label}; ${formatNumber(source.n)} observations${filter}.`; +} + +/** Production normalisation caveat (durations scaled to a common quantity). */ +function buildNormalizationNote(step: StepDetail): string | null { + const norm = step.normalization; + if (!norm) { + return null; + } + const unit = norm.unit ? ` ${norm.unit}` : ""; + return `Durations are normalised to ${formatNumber(norm.qty)}${unit} per batch (${norm.basis}, ${norm.window} window, ${formatNumber(norm.n_batches)} batches), so they read as "days per typical batch".`; +} + +/** Plain-language yield / consumption notes for production steps. */ +function buildProductionInsight(step: StepDetail): ProductionInsight | null { + if (step.type !== "production") { + return null; + } + let yieldNote: string | null = null; + let consumptionNote: string | null = null; + + const yd = step.yield_data; + if (yd && yd.stats.median != null && yd.reference > 0) { + const pct = ((yd.stats.median - yd.reference) / yd.reference) * 100; + yieldNote = `Median receipt ratio is ${formatNumber(yd.stats.median, { maximumFractionDigits: 1 })} vs ${formatNumber(yd.reference, { maximumFractionDigits: 1 })} reference (${formatSignedPct(pct)}); under-yield extends effective production duration per batch.`; + } + + const cd = step.consumption_data; + const agg = cd?.aggregate; + if (agg) { + const parts: string[] = []; + if (agg.weighted_variance_pct != null) { + parts.push( + `${formatSignedPct(agg.weighted_variance_pct)} weighted consumption variance`, + ); + } + if (agg.n_orders_off_bom) { + parts.push(`${formatNumber(agg.n_orders_off_bom)} off-BOM orders`); + } + if (agg.n_orders_substitution) { + parts.push( + `${formatNumber(agg.n_orders_substitution)} with substitutions`, + ); + } + if (parts.length > 0) { + consumptionNote = `Consumption: ${parts.join(", ")}.`; + } + } + + if (!yieldNote && !consumptionNote) { + return null; + } + return { yield: yieldNote, consumption: consumptionNote }; +} + +/** Distribution clustering descriptor from coefficient of variation / IQR. */ +function buildClusteringInsight(stats: StepStats): string | null { + const median = stats.median; + const mean = stats.mean; + const std = stats.std; + if (median == null || median <= 0) { + return null; + } + const p25 = stats.p25 ?? null; + const p75 = stats.p75 ?? null; + const iqrRatio = p25 != null && p75 != null ? (p75 - p25) / median : null; + const cv = mean != null && mean > 0 && std != null ? std / mean : null; + const metricParts: string[] = []; + if (cv != null) { + metricParts.push(`CV ${formatNumber(cv, { maximumFractionDigits: 2 })}`); + } + if (iqrRatio != null) { + metricParts.push( + `IQR/median ${formatNumber(iqrRatio, { maximumFractionDigits: 2 })}`, + ); + } + const metricText = + metricParts.length > 0 ? ` (${metricParts.join(", ")})` : ""; + + const score = iqrRatio ?? cv; + if (score == null) { + return null; + } + if (score < 0.35) { + return `Tightly clustered${metricText}: values sit close to the median, pointing to a structural floor rather than episodic variation.`; + } + if (score < 0.75) { + return `Moderately dispersed${metricText}: a mix of typical cases and longer events.`; + } + return `Long-tailed${metricText}: a minority of long events drive much of the spread.`; +} + +/** Tail-vs-typical trend note from stat-by-stat period deltas. */ +function buildTailTrendNote( + observations: Observation[], + range: TimeRange, +): string | null { + const deltas = computePeriodDeltas(observations, range); + const medianDelta = deltas.statDeltas.median; + const p95Delta = deltas.statDeltas.p95; + if (medianDelta == null || p95Delta == null) { + return null; + } + if (p95Delta - medianDelta > 15) { + return `The tail is worsening faster than the typical case: P95 moved ${formatSignedPct(p95Delta)} vs ${formatSignedPct(medianDelta)} for the median against the previous period, so the opportunity is increasingly driven by exceptions.`; + } + if (medianDelta - p95Delta > 15) { + return `The typical case is moving more than the tail: the median changed ${formatSignedPct(medianDelta)} vs ${formatSignedPct(p95Delta)} for P95 against the previous period, suggesting a broad shift rather than a few exceptions.`; + } + return null; +} + +/** Planning calibration impact: buffer released and residual late-event risk. */ +function buildCalibrationImpact( + step: StepDetail, + currentPlanDays: number | null, +): PlanningCalibrationImpact[] { + const targets: Array<{ + label: string; + days: number | null; + description: string; + }> = [ + { + label: "Median", + days: step.stats.median, + description: "Stretch target for operational excellence.", + }, + { + label: "P75", + days: step.stats.p75, + description: "Covers ~75% of observed events.", + }, + { + label: "P85", + days: step.stats.p85, + description: "More cautious; some late events remain expected.", + }, + { + label: "P95", + days: step.stats.p95, + description: "High-percentile planning reference.", + }, + ]; + + const values = step.durations; + return targets.map((threshold) => ({ + label: threshold.label, + days: threshold.days, + bufferDaysVsPlan: + currentPlanDays != null && threshold.days != null + ? currentPlanDays - threshold.days + : null, + pctExceeding: + threshold.days == null ? null : pctExceedingValue(values, threshold.days), + description: threshold.description, + })); +} + +function dwellRecommendationSummary( + step: StepDetail, + scenarios: DwellScenario[], + ctx: PlaybookContext, +): string { + const moderate = + scenarios.find((scenario) => scenario.label === "Moderate") ?? scenarios[0]; + if (!moderate) { + return "Investigate whether this step can be reduced; impact could not be quantified from current cost data."; + } + const target = `${formatNumber(moderate.targetDays, { maximumFractionDigits: 1 })} days`; + const playbook = PLAYBOOKS[step.type]; + const lead = playbook.dwellSummaryLead(ctx); + + const saving = + moderate.annualizedSaving == null + ? null + : formatCostForText( + moderate.annualizedSaving, + step.cost?.currency ?? null, + ); + return `${lead}; the moderate scenario caps long dwell at ${target}${saving ? ` and estimates ${saving} annualized saving` : ""}.`; +} + +function planningRecommendationSummary( + step: StepDetail, + safePlanningDays: number | null, + p95DeviationPct: number | null, + ctx: PlaybookContext, +): string { + if (safePlanningDays == null) { + return "Review the planning assumption once more observations are available."; + } + const playbook = PLAYBOOKS[step.type]; + const lead = playbook.planningSummaryLead(ctx); + + if (step.plan == null || step.plan <= 0) { + return `${lead}; consider setting a planning assumption around ${safePlanningDays} days if this service level is appropriate.`; + } + if ((p95DeviationPct ?? 0) > 0) { + return `${lead}; current timing exceeds plan and P95 suggests a safer planning assumption around ${safePlanningDays} days.`; + } + return `${lead}; the current plan is above the median and P95 of ${safePlanningDays} days provides context for whether the assumption can be tightened.`; +} + +function ceilOrNull(value: number | null | undefined): number | null { + return value == null ? null : Math.ceil(value); +} + +export function buildDwellOpportunityBrief( + step: StepDetail, + historicalStep: StepDetail, + range: TimeRange, + assumptions: CostAssumptions, + context: DwellBriefContext = {}, +): DwellOpportunityBrief { + const periodCost = periodCostOrNull( + step.monthly, + step.cost?.unit_price, + assumptions, + ); + const trend = computeTrend(historicalStep.observations, range); + const scenarios = buildDwellScenarios(step, range, periodCost); + const tailTrendNote = buildTailTrendNote(historicalStep.observations, range); + const diagnosis = diagnoseTimingShape(step.type, step.stats, trend); + if (tailTrendNote) { + diagnosis.push(tailTrendNote); + } + const evidenceFlags = buildEvidenceFlags(step, { + needsCost: true, + hasUnitCost: step.cost?.unit_price != null, + trend, + }); + const recipeMembership = buildRecipeMembership(context.productNodes); + const outOfCurrentRecipe = isOutOfCurrentRecipe( + context.siteNode, + recipeMembership, + ); + if (outOfCurrentRecipe) { + evidenceFlags.push({ + severity: "warning", + label: "Not in current recipe", + detail: + "This material is no longer reachable from the finished good in the current BOM/recipe, so reductions may not affect future batches.", + }); + } + const playbookCtx: PlaybookContext = { + stats: step.stats, + trend, + plan: step.plan, + }; + + return { + kind: "dwell", + stepType: step.type, + opportunityTrigger: buildDwellTrigger(step, periodCost, range), + confidence: buildConfidence(step, evidenceFlags), + guidance: buildGuidance(step.type), + periodCost, + annualizedCost: + periodCost == null ? null : periodCost * (12 / rangeMonths(range)), + currency: step.cost?.currency ?? null, + scenarios, + diagnosis, + evidenceFlags, + trend, + distributionInsight: buildDwellDistributionInsight(step), + highestCostMonth: computeHighestCostMonth( + step.monthly, + step.cost?.unit_price, + assumptions, + ), + recommendationSummary: dwellRecommendationSummary( + step, + scenarios, + playbookCtx, + ), + nextSteps: PLAYBOOKS[step.type].nextSteps, + + e2eLeverage: buildE2ELeverage(context.siteNode), + perProductImpact: computePerProductImpact(step, range, assumptions), + recipeMembership, + outOfCurrentRecipe, + supplier: buildSupplierSummary(step, range), + topEvidence: buildTopEvidence(step, range), + provenance: buildProvenance(step), + normalizationNote: buildNormalizationNote(step), + productionInsight: buildProductionInsight(step), + clustering: buildClusteringInsight(step.stats), + tailTrendNote, + firstUseDwell: buildFirstUseDwell(step, range), + }; +} + +export function buildPlanningOpportunityBrief( + step: StepDetail, + historicalStep: StepDetail, + range: TimeRange, + sourceKind: OpportunityBriefSourceKind = null, +): PlanningOpportunityBrief { + const trend = computeTrend(historicalStep.observations, range); + const currentPlanDays = step.plan; + // Observed P95 is shown raw (1 dp) across the brief; the rounded-up integer + // is used only for prose recommendations ("around N days"). + const p95PlanDays = ceilOrNull(step.stats.p95); + const medianDeviationPct = + currentPlanDays && currentPlanDays > 0 + ? (((step.stats.median ?? 0) - currentPlanDays) / currentPlanDays) * 100 + : null; + const meanDeviationPct = + currentPlanDays && currentPlanDays > 0 + ? (((step.stats.mean ?? 0) - currentPlanDays) / currentPlanDays) * 100 + : null; + const p95DeviationPct = + currentPlanDays && currentPlanDays > 0 && step.stats.p95 != null + ? ((step.stats.p95 - currentPlanDays) / currentPlanDays) * 100 + : null; + const calibrationDirection = + p95DeviationPct == null + ? "review" + : p95DeviationPct > 0 + ? "increase" + : "tighten"; + const evidenceFlags = buildEvidenceFlags(step, { + needsCost: false, + hasUnitCost: true, + trend, + }); + const confidence = buildConfidence(step, evidenceFlags); + const nExceedingPlan = + step.pct_exceeding_plan == null + ? null + : Math.round(step.stats.n * (step.pct_exceeding_plan / 100)); + const playbookCtx: PlaybookContext = { + stats: step.stats, + trend, + plan: step.plan, + }; + const tailTrendNote = buildTailTrendNote(historicalStep.observations, range); + const diagnosis = buildPlanningDiagnosis(step, trend, range, { + sourceKind, + p95DeviationPct, + medianDeviationPct, + meanDeviationPct, + confidence, + p95Days: p95PlanDays, + }); + if (tailTrendNote) { + diagnosis.push(tailTrendNote); + } + + return { + kind: "planning", + stepType: step.type, + opportunityTrigger: buildPlanningTrigger(step, p95DeviationPct), + confidence, + guidance: buildGuidance(step.type), + currentPlanDays, + p95Days: step.stats.p95, + medianDays: step.stats.median, + meanDays: step.stats.mean, + serviceLevelOptions: [ + { + label: "Median", + days: step.stats.median, + description: + "Typical performance; useful as an OpEx stretch reference, not a conservative planning parameter.", + }, + { + label: "P75", + days: step.stats.p75, + description: "Covers roughly three quarters of observed events.", + }, + { + label: "P85", + days: step.stats.p85, + description: + "A more cautious planning option where some late events remain expected.", + }, + { + label: "P95", + days: step.stats.p95, + description: + "High-percentile planning reference; not a guarantee that every event is covered.", + }, + ], + + medianDeviationPct, + meanDeviationPct, + p95DeviationPct, + pctExceedingPlan: step.pct_exceeding_plan ?? null, + nExceedingPlan, + calibrationDirection, + calibrationImpact: buildCalibrationImpact(step, currentPlanDays), + diagnosis, + evidenceFlags, + trend, + recommendationSummary: planningRecommendationSummary( + step, + p95PlanDays, + p95DeviationPct, + playbookCtx, + ), + nextSteps: PLAYBOOKS[step.type].nextSteps, + + supplier: buildSupplierSummary(step, range), + topEvidence: buildTopEvidence(step, range), + provenance: buildProvenance(step), + normalizationNote: buildNormalizationNote(step), + productionInsight: buildProductionInsight(step), + clustering: buildClusteringInsight(step.stats), + tailTrendNote, + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/recommendation-playbook.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/recommendation-playbook.ts new file mode 100644 index 00000000000..14155c981b7 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/opportunity/recommendation-playbook.ts @@ -0,0 +1,435 @@ +/** + * Per-step-type recommendation copy for opportunity briefs. + * + * The brief renderer keeps its layout — distribution charts, evidence tables, + * scenarios — but pulls all step-type-specific phrasing from this registry so + * a procurement brief talks about supplier OTIF and a QA-hold brief talks about + * lab throughput, while the underlying numeric model stays generic. + * + * Adding a new step type? Add an entry to PLAYBOOKS. Adding a new shape signal? + * Extend ShapeSignal here, then plumb it into `diagnoseTimingShape` and every + * playbook entry. + */ + +import type { StepStats, StepType } from "../../shared/types"; +import type { OpportunityTrend } from "./opportunity-utils"; + +/** Distribution-level signals that drive the diagnosis sentences. */ +export type ShapeSignal = + | "long_tail" + | "tight_high_median" + | "worsening" + | "improving" + | "mixed"; + +export interface PlaybookContext { + stats: StepStats; + trend: OpportunityTrend; + plan: number | null; +} + +export interface NextStepsChecklist { + scm: string[]; + opex: string[]; + planning: string[]; +} + +export interface StepTypePlaybook { + /** Maps a shape signal to a sentence tailored to this step type. */ + diagnosis: Record; + /** Lead clause for the dwell brief summary; gets combined with numeric target. */ + dwellSummaryLead: (ctx: PlaybookContext) => string; + /** Lead clause for the planning brief summary; gets combined with numeric target. */ + planningSummaryLead: (ctx: PlaybookContext) => string; + /** Three buckets of recommended next steps shown at the end of the brief. */ + nextSteps: NextStepsChecklist; +} + +/** Pick the most salient shape signal for a step. Mirrors the previous heuristic but is reusable. */ +export function shapeSignals( + stats: StepStats, + trend: OpportunityTrend, +): ShapeSignal[] { + const median = stats.median ?? 0; + const p25 = stats.p25 ?? 0; + const p75 = stats.p75 ?? 0; + const p95 = stats.p95 ?? 0; + const signals: ShapeSignal[] = []; + if (median > 0 && p95 > median * 2) { + signals.push("long_tail"); + } + if (median >= 3 && median > 0 && (p75 - p25) / median < 0.35) { + signals.push("tight_high_median"); + } + if (trend.direction === "worsening") { + signals.push("worsening"); + } + if (trend.direction === "improving") { + signals.push("improving"); + } + if (signals.length === 0) { + signals.push("mixed"); + } + return signals; +} + +const DWELL_PLAN_LEAD = (ctx: PlaybookContext, opName: string) => { + if (ctx.plan != null && ctx.plan > 0 && (ctx.stats.median ?? 0) > ctx.plan) { + return `Investigate reducing median ${opName} toward the ${ctx.plan} day planning assumption`; + } + return `Investigate ${opName} and the handoffs that drive it`; +}; + +export const PLAYBOOKS: Record = { + procurement: { + diagnosis: { + long_tail: + "A handful of long-lead-time POs are pulling the tail out — most likely supplier OTIF issues or single-source disruptions rather than the typical lead time.", + tight_high_median: + "Lead times cluster tightly around a high median, which usually indicates a structural supplier lead time or MOQ-driven cadence rather than episodic delays.", + worsening: + "Procurement lead times are getting worse versus the previous period; check whether a specific supplier, lane, or material category is degrading.", + improving: + "Procurement lead times are improving versus the previous period; confirm the gain is structural (new supplier, contract change) before locking in tighter planning assumptions.", + mixed: + "The opportunity is mixed: separate base lead time from supplier OTIF exceptions before recommending an action.", + }, + dwellSummaryLead: () => + "Investigate supplier OTIF, frame-contract MOQs, and whether dual-sourcing could shorten lead time", + planningSummaryLead: () => + "Align planned delivery time with the supplier's actual delivery profile", + nextSteps: { + scm: [ + "Pull supplier OTIF for the top contributors and check whether one or two suppliers explain the tail.", + "Review MOQ vs. lead time trade-offs: a smaller MOQ with more frequent deliveries could reduce dwell upstream.", + "Check whether frame contracts or VMI arrangements could shrink the planning buffer for high-volume materials.", + ], + + opex: [ + "Inspect receipt-to-warehouse posting delay (system posting date vs. physical receipt) — paperwork lag can inflate apparent lead time.", + "Confirm the material booking process at goods receipt is not adding avoidable days.", + ], + + planning: [ + "Compare observed lead time to the planned lead time and supplier-quoted lead time; identify gaps.", + "Validate whether the planning assumption protects the appropriate service level given variability.", + ], + }, + }, + + raw_material_dwell: { + diagnosis: { + long_tail: + "A few batches sit for very long — likely safety-stock excess, expired quarantine holds, or call-offs that arrived ahead of plan.", + tight_high_median: + "Raw materials consistently sit for a similar period, suggesting safety-stock policy or supplier delivery cadence sets the floor — not random variability.", + worsening: + "Raw material dwell is rising versus the previous period; check whether replenishment cadence is out of sync with consumption.", + improving: + "Raw material dwell is improving; confirm it is not driven by stockouts before reducing safety days.", + mixed: + "Separate chronic high-stock materials from episodic over-deliveries before deciding where to push.", + }, + dwellSummaryLead: (ctx) => DWELL_PLAN_LEAD(ctx, "raw-material dwell"), + planningSummaryLead: () => + "Calibrate MRP reorder point and safety days against actual consumption rate", + nextSteps: { + scm: [ + "Review safety stock and reorder-point policy for the highest-dwell materials.", + "Check call-off cadence: are deliveries arriving in larger lots than consumption justifies?", + "Confirm supplier MOQ is not the constraint forcing oversized batches.", + ], + + opex: [ + "Check for quarantine holds or expiry-driven quarantine that inflate dwell on specific batches.", + "Review whether FEFO/FIFO is being followed at consumption.", + ], + + planning: [ + "Compare observed dwell to MRP horizon and safety days; identify materials where MRP is over-stocking.", + "Validate planned consumption rate against actual; mismatched rates over-inflate buffer.", + ], + }, + }, + + intermediate_dwell: { + diagnosis: { + long_tail: + "Intermediate batches that wait far longer than typical usually point to batch-size mismatch — upstream is producing in larger lots than downstream can consume.", + tight_high_median: + "Intermediate dwell is consistent and elevated, which usually indicates a structural WIP buffer between two scheduling cadences.", + worsening: + "Intermediate dwell is rising; check whether upstream production is running ahead of downstream demand or whether downstream sequencing has changed.", + improving: + "Intermediate dwell is improving; confirm whether sequencing changes or batch-size adjustments are sustainable.", + mixed: + "Look at whether elevated dwell is concentrated in particular batches or production campaigns before recommending an action.", + }, + dwellSummaryLead: (ctx) => + DWELL_PLAN_LEAD(ctx, "intermediate-stage WIP dwell"), + planningSummaryLead: () => + "Re-examine the planned WIP buffer between the upstream and downstream production steps", + nextSteps: { + scm: [ + "Check whether scheduling rules force intermediate stocking above what the next step needs.", + ], + + opex: [ + "Compare upstream and downstream batch sizes — a mismatch is the most common cause of intermediate dwell.", + "Review production scheduling and sequencing: is the next step starved or waiting on equipment, not material?", + "Inspect equipment occupancy to confirm dwell is not a symptom of a downstream bottleneck.", + ], + + planning: [ + "Confirm the WIP buffer assumption in the production plan reflects actual upstream/downstream linkage.", + "Check whether changeovers or campaign sequencing imply a buffer that could be reduced.", + ], + }, + }, + + production: { + diagnosis: { + long_tail: + "A few orders take far longer than the typical campaign — most often driven by extended changeovers, equipment unavailability, or a few low-yield runs.", + tight_high_median: + "Production runs cluster around a high duration, suggesting the planned production time is the floor rather than random variation.", + worsening: + "Production duration is increasing; check changeovers, OEE, and whether a specific line or product mix is degrading.", + improving: + "Production duration is improving; confirm whether the improvement is driven by mix, OEE, or a one-off and whether it is sustainable.", + mixed: + "Separate steady-state run time from changeover-heavy or low-yield campaigns before drawing conclusions.", + }, + dwellSummaryLead: (ctx) => DWELL_PLAN_LEAD(ctx, "production duration"), + planningSummaryLead: () => + "Re-calibrate the planned production time against actual run time", + nextSteps: { + scm: [ + "Check whether material availability is causing the tail (raw material stockouts mid-run).", + ], + + opex: [ + "Inspect changeover patterns: are campaign sizes minimising changeovers?", + "Review cycle time and line utilisation; identify whether the bottleneck is consistent or shifting.", + "Check OEE for the production line and whether quality losses, breakdowns, or speed losses are dominant.", + ], + + planning: [ + "Compare actual run time to the planned production time.", + "Confirm planned versus actual yield — under-yield extends effective production duration per batch.", + ], + }, + }, + + qa_hold: { + diagnosis: { + long_tail: + "A few batches sit in QA hold far longer than typical — typically driven by retests, off-spec investigations, or regulatory holds on specific materials.", + tight_high_median: + "QA hold time is consistent and elevated, suggesting standard analytical cycle time and lab batching, not exceptions, set the floor.", + worsening: + "QA hold times are rising; check lab throughput, sample backlog, retest rate, and whether testing methods have changed.", + improving: + "QA hold times are improving; confirm whether faster analytical methods or reduced retest rates are sustainable.", + mixed: + "Identify whether elevated hold time is driven by sample batching, retests, or specific test methods before acting.", + }, + dwellSummaryLead: (ctx) => DWELL_PLAN_LEAD(ctx, "QA hold time"), + planningSummaryLead: () => + "Update the planned QA lead time per material to reflect actual analytical cycle time", + nextSteps: { + scm: [ + "Confirm whether customer release commitments accommodate the actual QA hold time.", + ], + + opex: [ + "Review lab throughput and whether analyses are batched in a way that delays release.", + "Check the retest rate by material — a high retest rate doubles or triples effective QA time.", + "Identify whether any regulatory or stability-test holds apply to specific batches.", + ], + + planning: [ + "Calibrate QA lead time per material against the observed P75/P95.", + "Confirm the planning parameter protects the appropriate service level given retest variability.", + ], + }, + }, + + post_qa_ship: { + diagnosis: { + long_tail: + "A few batches wait far longer to ship than typical — most often driven by container fill, customer call-off, or freight cadence on specific lanes.", + tight_high_median: + "Post-QA dwell is consistent and elevated, suggesting a structural shipping cadence (weekly container, full-truckload threshold) is the driver.", + worsening: + "Post-QA dwell is rising; check container fill rules, freight booking lead time, and customer call-off behaviour.", + improving: + "Post-QA dwell is improving; confirm whether smaller containers, more frequent shipments, or mix changes explain it.", + mixed: + "Distinguish dwell that is intentional (container fill) from dwell that is avoidable (booking delays) before acting.", + }, + dwellSummaryLead: (ctx) => DWELL_PLAN_LEAD(ctx, "post-QA dwell"), + planningSummaryLead: () => + "Update planned shipping lead time to reflect actual container-fill and booking cadence", + nextSteps: { + scm: [ + "Review container fill strategy — is dwell intentional while building a full container?", + "Check freight cadence and customer call-off behaviour for the dominant lanes.", + "Confirm booking lead time at the forwarder allows for the observed dwell.", + ], + + opex: [ + "Inspect staging, label rework, and any physical handling after QA release.", + "Confirm the system goods-issue posting date matches physical gate-out — paperwork lag inflates apparent dwell.", + ], + + planning: [ + "Compare planned shipping lead time to observed median and P95.", + "Decide whether dwell reduction is a planning calibration issue or an operational change.", + ], + }, + }, + + transit: { + diagnosis: { + long_tail: + "A few shipments take far longer than typical — usually customs holds, demurrage, or a single problematic lane.", + tight_high_median: + "Transit time is consistent and elevated, suggesting the lane structure (mode, route) — not exceptions — is the driver.", + worsening: + "Transit time is rising; check carrier performance, customs hold rate, and whether the lane mix has changed.", + improving: + "Transit time is improving; confirm whether the gain is from a carrier change, mode mix, or favourable customs cycle.", + mixed: + "Identify whether elevated transit is structural to a lane or driven by exception events before acting.", + }, + dwellSummaryLead: (ctx) => DWELL_PLAN_LEAD(ctx, "transit time"), + planningSummaryLead: () => + "Align planned transit time per lane with carrier-actual performance", + nextSteps: { + scm: [ + "Pull carrier performance for the dominant lanes and check whether one or two carriers explain the tail.", + "Review the customs hold rate by lane; investigate causes for any lane with persistent holds.", + "Confirm incoterms and ownership of dwell time at customs — internal vs. customer-managed.", + ], + + opex: [ + "Inspect paperwork handoffs (booking, customs documentation) — internal delays add to transit time.", + ], + + planning: [ + "Calibrate planned transit time per lane against observed P75/P95.", + "Confirm the lane mix in the plan matches actual shipment routing.", + ], + }, + }, + + destination_dwell: { + diagnosis: { + long_tail: + "A few hub stockholdings persist far longer than typical — usually slow-moving SKUs or customer pull that did not materialise.", + tight_high_median: + "Hub dwell is consistent and elevated, suggesting the hub stocking policy (days-of-cover) sets the floor, not exception events.", + worsening: + "Hub dwell is rising; check whether customer call-off is slowing or whether hub allocation has been over-provisioned.", + improving: + "Hub dwell is improving; confirm whether hub stocking has been right-sized or whether customer demand has shifted.", + mixed: + "Separate stuck SKUs from healthy stock turn before recommending policy changes.", + }, + dwellSummaryLead: (ctx) => DWELL_PLAN_LEAD(ctx, "hub dwell"), + planningSummaryLead: () => + "Align hub stocking days-of-cover with the actual customer call-off cadence", + nextSteps: { + scm: [ + "Review hub allocation policy: are units pushed to the hub ahead of confirmed customer call-off?", + "Check whether route reassignment between hubs could clear slow-moving stock.", + "Confirm minimum stocking levels at the hub are aligned with current demand profile.", + ], + + opex: [ + "Inspect local repackaging or rework time at the hub.", + "Identify any SKUs whose hub dwell is dominated by aged stock.", + ], + + planning: [ + "Compare planned days-of-cover to observed P75 at the hub.", + "Validate whether the planning model treats hub stock as a service buffer or as a pull-driven inventory.", + ], + }, + }, +}; + +export function diagnosisFor( + stepType: StepType, + signals: ShapeSignal[], +): string[] { + const playbook = PLAYBOOKS[stepType]; + + const seen = new Set(); + const out: string[] = []; + for (const signal of signals) { + if (seen.has(signal)) { + continue; + } + seen.add(signal); + const sentence = playbook.diagnosis[signal]; + if (sentence) { + out.push(sentence); + } + } + return out; +} + +const FIRST_EVIDENCE_BY_STEP_TYPE: Record = { + procurement: [ + "Check the supplier and PO lines behind the longest observations.", + "Compare observed lead time to the planned lead time and any supplier-quoted lead time.", + "Look for one vendor, material, or purchasing cadence explaining the tail.", + ], + + raw_material_dwell: [ + "Inspect the oldest receipts and the consumption dates they eventually served.", + "Check safety-stock and reorder-point settings for the material.", + "Validate whether quarantine, expiry, or FEFO/FIFO practice explains long holds.", + ], + + intermediate_dwell: [ + "Compare upstream and downstream batch sizes for the affected intermediates.", + "Check whether long waits cluster around specific campaigns or equipment.", + "Validate whether downstream sequencing or capacity is the binding constraint.", + ], + + production: [ + "Review orders with the longest normalized durations and their changeover context.", + "Check OEE, downtime, and speed-loss data for the relevant line.", + "Compare actual duration to the planned production time and yield variance.", + ], + + qa_hold: [ + "Check batches with the longest release delays for retests or investigations.", + "Review lab queue and method cycle time for the material.", + "Confirm whether holds are regulatory/stability requirements or avoidable waits.", + ], + + post_qa_ship: [ + "Inspect batches with long QA-release-to-shipment gaps by customer or lane.", + "Check freight booking and container-fill rules for the dominant route.", + "Validate whether the system goods-issue posting date matches physical gate-out.", + ], + + transit: [ + "Break long transit observations down by lane, carrier, and customs status.", + "Check whether the apparent trend is route mix or true carrier performance.", + "Review documentation handoffs for customs or demurrage delays.", + ], + + destination_dwell: [ + "Identify whether aged hub stock is concentrated in a few SKUs or customers.", + "Compare hub allocation to actual customer call-off cadence.", + "Check whether stock was pushed ahead of confirmed demand.", + ], +}; +export function firstEvidenceFor(stepType: StepType): string[] { + return FIRST_EVIDENCE_BY_STEP_TYPE[stepType]; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product.tsx new file mode 100644 index 00000000000..146363fa55f --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product.tsx @@ -0,0 +1,612 @@ +import { useCallback, useEffect, useState, useMemo } from "react"; + +import { Tooltip } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { DWELL_TYPES } from "../shared/categories"; +import { + useCostParams, + useOutlierSetting, + computePeriodCost, + formatCost, + formatNumber, +} from "../shared/cost"; +import { + AnalysisSettingsPanel, + HeaderActionButtons, +} from "../shared/header-actions"; +import { MEASURE_LABELS, useBaseMeasure } from "../shared/measure-context"; +import { useProcurementBasis } from "../shared/procurement-basis-context"; +import { filterGraphNodeByDateRange } from "../shared/range-filter"; +import { ScopeSelect } from "../shared/scope-select"; +import { SegmentedControl } from "../shared/segmented-control"; +import { StatChip } from "../shared/stat-chip"; +import { StepDetailPanel } from "../shared/step-detail-panel"; +import { trackSupplyChainInteraction } from "../shared/telemetry"; +import { cutoffForRange, timeRangeLongLabel } from "../shared/time-range"; +import { useTimeRange } from "../shared/time-range-context"; +import { useSearchParams } from "../shared/use-search-params"; +import { CategoryView } from "./product/category-view"; +import { E2EWhatIf } from "./product/e2e-what-if"; +import { ProcessGraph } from "./product/process-graph"; +import { recomputeBatchTimelines } from "./product/recompute-batch-timelines"; +import { PipelineHeader } from "./product/shared/pipeline-header"; +import { PipelineWaterfall } from "./product/shared/pipeline-waterfall"; +import { ALL_SEGMENTS, type SegmentId } from "./product/whatif"; + +import type { GraphData, GraphNode } from "../shared/types"; + +type ViewMode = "category" | "canvas"; + +const DEFAULT_ACTIVE_SEGMENTS = ALL_SEGMENTS.filter( + (id) => id !== "procurement", +); + +function sameSegments( + left: readonly SegmentId[], + right: Set, +): boolean { + return left.length === right.size && left.every((id) => right.has(id)); +} + +// Fill the layout's main area (a flex column) and clamp our own height to it so +// the content pane can scroll internally instead of overflowing the viewport. +// `minH:0` is required for the inner `overflow:auto` pane to actually scroll. +const rootStyle = css({ + display: "flex", + flexDirection: "column", + flex: "1", + minH: "0", +}); +const headerBar = css({ + borderBottomWidth: "1px", + borderColor: "bd.subtle", + px: "6", + py: "3", + flexShrink: 0, +}); +const headerRow = css({ + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", + gap: "4", +}); +const titleCol = css({ + flex: "1", + minW: "0", + display: "flex", + flexDirection: "column", + gap: "1", +}); +const statsRow = css({ + display: "flex", + alignItems: "center", + gap: "0", + textStyle: "sm", +}); +// The product view-mode switcher stays prominent; analysis assumptions live +// behind the shared settings cog. +const controlsCol = css({ + display: "flex", + flexDirection: "column", + alignItems: "flex-end", + gap: "2", + flexShrink: 0, +}); +const controlsBottomRow = css({ + display: "flex", + alignItems: "center", + gap: "2", +}); +const contentBase = css({ px: "6", py: "3", flex: "1", minH: "0" }); +const overflowHidden = css({ overflow: "hidden" }); +const overflowAuto = css({ overflow: "auto" }); +const paneShow = css({ h: "full", minH: "0" }); +const hidden = css({ display: "none" }); +const pipelineWrap = css({ + flexShrink: 0, + borderTopWidth: "1px", + borderColor: "bd.subtle", + overflow: "hidden", + transition: "[height 200ms]", +}); +const pipelineExpandedH = css({ h: "[58vh]" }); +const pipelineAutoH = css({ h: "auto" }); +const emptyPipelineRow = css({ + px: "6", + py: "3", + display: "flex", + alignItems: "center", + gap: "3", + h: "7", +}); +const emptyPipelineTitle = css({ + textStyle: "base", + fontWeight: "medium", + color: "fg.heading", +}); +const emptyPipelineNote = css({ textStyle: "sm", color: "fg.subtle" }); +const collapsedPad = css({ px: "6", py: "3" }); +const collapsedStack = css({ + display: "flex", + flexDirection: "column", + gap: "4", +}); +// Horizontal by default (two hints side-by-side), wrapping to a stack only when +// space is tight — keeps the header short. Same spirit as the KPI chips. +const legendWrap = css({ + display: "flex", + flexWrap: "wrap", + alignItems: "center", + columnGap: "3", + rowGap: "1", +}); +const legendTooltipTrigger = css({ + display: "inline-flex", + mr: "3", + cursor: "help", +}); +const legendRow = css({ display: "flex", alignItems: "center", gap: "1.5" }); +const legendBadgeBase = css({ + display: "inline-flex", + alignItems: "center", + gap: "0.5", + textStyle: "xxs", + fontWeight: "medium", + borderRadius: "sm", + px: "1", + py: "[1px]", + borderWidth: "1px", + borderStyle: "solid", +}); +const legendBadgeGood = css({ + bg: "status.success.bg.subtle", + color: "status.success.fg.body", + borderColor: "status.success.bd.subtle", +}); +const legendBadgeBad = css({ + bg: "status.error.bg.subtle", + color: "status.error.fg.body", + borderColor: "status.error.bd.subtle", +}); +const legendLabel = css({ textStyle: "xs", color: "fg.subtle" }); +const legendClock = css({ flexShrink: 0 }); + +interface OverviewProps { + graph: GraphData; + productId: string; + selectedStepId: string | null; + onStepSelect: (stepId: string | null) => void; +} + +function periodTotalCost( + dwellNodes: GraphNode[], + waccRate: number, + storageCost: number, +): number { + return dwellNodes.reduce( + (acc, count) => + acc + + computePeriodCost( + count.monthly, + count.cost?.unit_price, + waccRate, + storageCost, + ), + 0, + ); +} + +const LegendClockIcon = () => { + return ( + + ); +}; + +const PlanningParamLegend = () => { + const { measure } = useBaseMeasure(); + const measureLabel = MEASURE_LABELS[measure].toLowerCase(); + return ( + +
+
+ + + 14d + + Under plan +
+
+ + + 14d + + Above plan +
+
+
+ ); +}; +export const Overview = ({ + graph, + productId, + selectedStepId, + onStepSelect, +}: OverviewProps) => { + const [viewMode, setViewMode] = useState("category"); + const { timeRange } = useTimeRange(); + const { currency, setAnalysisSettings, waccRate, storageCost } = + useCostParams(); + const { excludeOutliers } = useOutlierSetting(); + const { basis: procurementBasis } = useProcurementBasis(); + const [searchParams, setSearchParams] = useSearchParams(); + const [settingsOpen, setSettingsOpen] = useState(false); + const pipelineExpanded = searchParams.get("pipeline") === "expanded"; + useEffect(() => { + setAnalysisSettings(graph.analysis_settings); + }, [graph.analysis_settings, setAnalysisSettings]); + const setPipelineExpanded = useCallback( + (expanded: boolean) => { + setSearchParams( + (prev) => { + const next = new URLSearchParams(prev); + if (expanded) { + next.set("pipeline", "expanded"); + } else { + next.delete("pipeline"); + } + return next; + }, + { replace: true }, + ); + }, + [setSearchParams], + ); // Segment toggle: which of the four pipeline segments are currently + // included in the waterfall totals, KPI tiles, and lever list. + // Persisted as ?segments= when the user differs + // from the default; absent param == procurement off, remaining segments on. + const activeSegments = useMemo>(() => { + const raw = searchParams.get("segments"); + if (!raw) { + return new Set(DEFAULT_ACTIVE_SEGMENTS); + } + const ids = raw + .split(",") + .filter((id): id is SegmentId => + (ALL_SEGMENTS as readonly string[]).includes(id), + ); + return new Set(ids); + }, [searchParams]); + const setActiveSegments = useCallback( + (next: Set) => { + setSearchParams( + (prev) => { + const params = new URLSearchParams(prev); // Canonical order keeps the URL stable regardless of toggle + // order. Drop the param entirely when the default selection is restored. + const ordered = ALL_SEGMENTS.filter((id) => next.has(id)); + if (sameSegments(DEFAULT_ACTIVE_SEGMENTS, next)) { + params.delete("segments"); + } else { + params.set("segments", ordered.join(",")); + } + return params; + }, + { replace: true }, + ); + }, + [setSearchParams], + ); + const handleSegmentToggle = useCallback( + (id: SegmentId) => { + const next = new Set(activeSegments); + if (next.has(id)) { + next.delete(id); + } else { + next.add(id); + } + setActiveSegments(next); + }, + [activeSegments, setActiveSegments], + ); // Pipeline route (e.g. shipping destination) is lifted here so the + // selection survives collapse/expand of the simulator. Persisted as + // ?route= when set; omitted if no param is present and the + // child renders a route picker for the first available route. + const activeRouteParam = searchParams.get("route") ?? undefined; + const setActiveRoute = useCallback( + (code: string) => { + setSearchParams( + (prev) => { + const params = new URLSearchParams(prev); + if (!code) { + params.delete("route"); + } else { + params.set("route", code); + } + return params; + }, + { replace: true }, + ); + }, + [setSearchParams], + ); + const handleStepClick = useCallback( + (stepId: string) => { + trackSupplyChainInteraction({ + interaction: "product_step_selected", + productId, + source: viewMode === "canvas" ? "product_graph" : "category_view", + stepId, + }); + onStepSelect(stepId); + }, + [onStepSelect, productId, viewMode], + ); + const handlePanelClose = useCallback(() => { + onStepSelect(null); + }, [onStepSelect]); + const filteredGraph = useMemo((): GraphData => { + const filteredNodes = graph.nodes.map((count) => + filterGraphNodeByDateRange( + count, + timeRange, + excludeOutliers, + procurementBasis, + ), + ); + const bt = graph.batch_timelines; + if (!bt || bt.batches.length === 0) { + return { ...graph, nodes: filteredNodes }; + } + const cutoff = cutoffForRange(timeRange); + const filteredBatches = cutoff + ? bt.batches.filter((right) => { + const endDate = right.delivery_date; + return endDate != null && endDate.slice(0, 7) >= cutoff; + }) + : bt.batches; + const filteredBT = recomputeBatchTimelines( + filteredBatches, + bt, + excludeOutliers, + ); + return { + ...graph, + nodes: filteredNodes, + batch_timelines: filteredBT.timelines, + pipeline_summary: filteredBT.pipeline, + }; + }, [graph, timeRange, excludeOutliers, procurementBasis]); + const summaryStats = useMemo(() => { + const bt = filteredGraph.batch_timelines; + const totalSeg = bt?.segments?.total_days; + const totalMean = totalSeg?.mean != null ? Math.round(totalSeg.mean) : null; + const totalMedian = + totalSeg?.median != null ? Math.round(totalSeg.median) : null; + if (totalMean == null) { + return { totalMean: null, totalMedian: null, dwellCost: null }; + } + const nodes = filteredGraph.nodes; + const dwellNodes = nodes.filter( + (count) => DWELL_TYPES.includes(count.type) && count.stats.n > 0, + ); + const dwellCost = periodTotalCost(dwellNodes, waccRate, storageCost); + return { + totalMean, + totalMedian, + dwellCost: dwellCost > 0 ? dwellCost : null, + }; + }, [filteredGraph, waccRate, storageCost]); + const productCurrency = useMemo(() => { + const counts = new Map(); + for (const node of graph.nodes) { + const nodeCurrency = node.cost?.currency; + if (nodeCurrency) { + counts.set(nodeCurrency, (counts.get(nodeCurrency) ?? 0) + 1); + } + } + let best: string | null = null; + let bestN = 0; + for (const [nodeCurrency, count] of counts) { + if (count > bestN) { + best = nodeCurrency; + bestN = count; + } + } + return best ?? currency; + }, [graph.nodes, currency]); + return ( +
+ {/* Header bar */} +
+
+ {/* Left: scope picker (doubles as title) + stats */} +
+ +
+ {summaryStats.totalMean != null && ( + + )} + {summaryStats.totalMedian != null && ( + + )} + {summaryStats.dwellCost != null && ( + + )} +
+
+ + {/* Right: primary view controls + lower-frequency settings/help. */} +
+
+ + { + trackSupplyChainInteraction({ + interaction: "product_view_mode_changed", + productId, + source: "product_page", + }); + setViewMode(nextViewMode); + }} + options={[ + { value: "category", label: "Category" }, + { value: "canvas", label: "Canvas" }, + ]} + /> + + { + trackSupplyChainInteraction({ + interaction: settingsOpen + ? "settings_closed" + : "settings_opened", + productId, + source: "product_page", + }); + setSettingsOpen((open) => !open); + }} + docContext="product" + /> +
+
+
+ {settingsOpen && ( + setSettingsOpen(false)} /> + )} +
+ + {/* Content */} +
+
+ +
+
+ +
+
+ +
+ {(() => { + if ( + !Object.values(filteredGraph.pipeline_summary).some( + (product) => product.total_mean > 0, + ) + ) { + return ( +
+

End-to-End Pipeline

+ + No traceable batch pipeline for this period/product + +
+ ); + } // Resolve active route: prefer the URL param when it points at a + // route that exists for this product, otherwise fall back to + // the first route so the picker has a sensible default. + const routeKeys = Object.keys(filteredGraph.pipeline_summary); + const resolvedRoute = + activeRouteParam && routeKeys.includes(activeRouteParam) + ? activeRouteParam + : (routeKeys[0] ?? ""); + return pipelineExpanded ? ( + setPipelineExpanded(false)} + onStepDrill={onStepSelect} + activeSegments={activeSegments} + onSegmentToggle={handleSegmentToggle} + activeRoute={resolvedRoute} + onActiveRouteChange={setActiveRoute} + /> + ) : ( +
+
+ setPipelineExpanded(true)} + /> + + +
+
+ ); + })()} +
+ + {selectedStepId && ( + + )} +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/category-view.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/category-view.tsx new file mode 100644 index 00000000000..097566ca9b1 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/category-view.tsx @@ -0,0 +1,262 @@ +import { useState, useMemo } from "react"; + +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { CATEGORIES, isDwellType } from "../../shared/categories"; +import { useCostParams, computePeriodCost } from "../../shared/cost"; +import { CategoryIcon } from "./shared/category-icon"; +import { StepCard } from "./shared/step-card"; + +import type { GraphData, GraphNode, StepType } from "../../shared/types"; + +const board = css({ + display: "flex", + gap: "0", + minH: "[500px]", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "lg", + overflow: "hidden", + bg: "bgSolid.min", +}); +const column = css({ + flex: "1", + minW: "0", + borderRightWidth: "1px", + borderRightStyle: "solid", + borderColor: "bd.subtle", + _last: { borderRightWidth: "0" }, +}); +const colHeader = css({ + px: "4", + py: "3", + borderBottomWidth: "1px", + borderColor: "bd.subtle", +}); +const colHeaderRow = css({ + display: "flex", + alignItems: "center", + justifyContent: "space-between", +}); +const colHeaderTitle = css({ display: "flex", alignItems: "center", gap: "2" }); +const colLabel = css({ + textStyle: "sm", + fontWeight: "medium", + color: "fg.heading", +}); +const sortGroup = css({ display: "flex", alignItems: "center", gap: "1" }); +const colBody = css({ + p: "3", + display: "flex", + flexDirection: "column", + gap: "3", +}); +const emptyNote = css({ + textStyle: "xs", + color: "fg.subtle", + fontStyle: "italic", + px: "1", +}); +const sortBtnBase = css({ + display: "flex", + alignItems: "center", + gap: "0.5", + textStyle: "xxs", + fontWeight: "medium", + px: "1.5", + py: "0.5", + borderRadius: "sm", + transition: "colors", + cursor: "pointer", +}); +const sortBtnActive = css({ color: "fg.heading", bg: "bg.subtle" }); +const sortBtnInactive = css({ + color: "fg.subtle", + _hover: { color: "fg.muted", bg: "bg.subtle" }, +}); +const sortArrow = css({ flexShrink: 0 }); + +interface CategoryViewProps { + graph: GraphData; + onStepClick: (stepId: string) => void; + timeRange?: string; +} + +type SortKey = "default" | "duration" | "cost"; +type SortDir = "asc" | "desc"; + +function computeNodeCost( + node: GraphNode, + waccRate: number, + storageCost: number, +): number { + return computePeriodCost( + node.monthly, + node.cost?.unit_price, + waccRate, + storageCost, + ); +} + +const SortButton = ({ + label, + active, + dir, + onClick, +}: { + label: string; + active: boolean; + dir?: SortDir; + onClick: () => void; +}) => { + return ( + + ); +}; +export const CategoryView = ({ + graph, + onStepClick, + timeRange, +}: CategoryViewProps) => { + const { waccRate, storageCost } = useCostParams(); + const [sortOverrides, setSortOverrides] = useState< + Record + >({}); + const grouped = useMemo(() => { + return CATEGORIES.filter((column2) => !column2.hidden).map((cat) => ({ + ...cat, + nodes: graph.nodes.filter((count) => cat.types.includes(count.type)), + })); + }, [graph.nodes]); + const effectiveSortKeys = useMemo(() => { + const keys: Record = {}; + for (const cat of grouped) { + keys[cat.key] = { key: "duration", dir: "desc" }; + } + for (const [key, value] of Object.entries(sortOverrides)) { + if (value === null) { + delete keys[key]; + } else { + keys[key] = value; + } + } + return keys; + }, [grouped, sortOverrides]); + const sortedGrouped = useMemo(() => { + return grouped.map((cat) => { + const sort = effectiveSortKeys[cat.key]; + if (!sort || sort.key === "default") { + return cat; + } + const sorted = [...cat.nodes].sort((left, right) => { + let va = 0; + let vb = 0; + if (sort.key === "duration") { + va = left.stats.median ?? 0; + vb = right.stats.median ?? 0; + } else if (sort.key === "cost") { + va = computeNodeCost(left, waccRate, storageCost); + vb = computeNodeCost(right, waccRate, storageCost); + } + return sort.dir === "desc" ? vb - va : va - vb; + }); + return { ...cat, nodes: sorted }; + }); + }, [grouped, effectiveSortKeys, waccRate, storageCost]); + const toggleSort = (catKey: string, key: SortKey) => { + setSortOverrides((prev) => { + const cur = effectiveSortKeys[catKey]; + if (cur?.key === key) { + if (cur.dir === "desc") { + return { ...prev, [catKey]: { key, dir: "asc" } }; + } + return { ...prev, [catKey]: null }; + } + return { ...prev, [catKey]: { key, dir: "desc" } }; + }); + }; + const hasDwellType = (types: string[]) => + types.some((threshold) => isDwellType(threshold as StepType)); + return ( +
+ {sortedGrouped.map((cat) => { + const sort = effectiveSortKeys[cat.key]; + return ( +
+
+
+
+ + {cat.label} +
+ {cat.nodes.length > 1 && ( +
+ toggleSort(cat.key, "duration")} + /> + + {hasDwellType(cat.types) && ( + toggleSort(cat.key, "cost")} + /> + )} +
+ )} +
+
+
+ {cat.nodes.map((node) => ( + onStepClick(node.id)} + timeRange={timeRange} + /> + ))} + {cat.nodes.length === 0 &&

No steps

} +
+
+ ); + })} +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if.tsx new file mode 100644 index 00000000000..52ba3d29c93 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if.tsx @@ -0,0 +1,356 @@ +import { useCallback, useMemo, useState } from "react"; + +import { Button } from "@hashintel/ds-components"; +import { css } from "@hashintel/ds-helpers/css"; + +import { + formatCost, + formatNumber, + useCostParams, + useOutlierSetting, +} from "../../shared/cost"; +import { BindingLever } from "./e2e-what-if/binding-lever"; +import { KpiTile } from "./e2e-what-if/what-if-kpis"; +import { PipelineHeader } from "./shared/pipeline-header"; +import { PipelineWaterfall } from "./shared/pipeline-waterfall"; +import { + aggregateSimulation, + isCapActive, + selectTopLevers, + type SegmentId, +} from "./whatif"; + +import type { TimeRange } from "../../shared/time-range"; +import type { GraphData } from "../../shared/types"; + +interface E2EWhatIfProps { + graph: GraphData; + timeRange: TimeRange; + onCollapse: () => void; + onStepDrill: (stepId: string) => void; + /** Segments currently included in totals, KPIs and the lever list. */ + activeSegments: Set; + /** Toggle a segment on/off when its legend chip is clicked. */ + onSegmentToggle: (id: SegmentId) => void; + /** Controlled active route (lifted from Overview so collapse/expand + * doesn't reset the selection). */ + activeRoute: string; + onActiveRouteChange: (route: string) => void; +} + +const MAX_VISIBLE_LEVERS = 5; + +const root = css({ + h: "full", + display: "flex", + flexDirection: "column", + px: "6", + py: "3", + minH: "0", + overflow: "hidden", +}); +const headerMb = css({ mb: "3" }); +// `gridTemplateColumns` is set inline: Panda's arbitrary-value codegen drops a +// space-separated track list like `[1fr_360px_280px]` (it only emits function +// forms such as `repeat(...)`), which silently collapsed this to one column. +const grid = css({ display: "grid", gap: "4", flex: "1", minH: "0" }); +const gridCols = "1fr 360px 220px"; +const leftCol = css({ minW: "0", overflow: "auto", pr: "2" }); +const callout = css({ + mt: "4", + borderRadius: "md", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bg.subtle", + px: "3", + py: "2", + textStyle: "xs", + color: "fg.muted", + lineHeight: "snug", +}); +const calloutStrong = css({ fontWeight: "medium", color: "fg.heading" }); +const sideCol = css({ + minW: "0", + display: "flex", + flexDirection: "column", + minH: "0", +}); +const sideHeaderRow = css({ + display: "flex", + alignItems: "center", + justifyContent: "space-between", + mb: "2", +}); +const sectionTitle = css({ + textStyle: "sm", + fontWeight: "medium", + color: "fg.heading", +}); +const sectionTitleMb = css({ + textStyle: "sm", + fontWeight: "medium", + color: "fg.heading", + mb: "2", +}); +const leverList = css({ + display: "flex", + flexDirection: "column", + gap: "2", + overflow: "auto", + pr: "1", + flex: "1", + minH: "0", +}); +const leverEmpty = css({ textStyle: "xs", color: "fg.subtle", py: "4" }); +// Left-aligned within the lever column; the control is a ds `Button` (linkSubtle). +const showToggle = css({ alignSelf: "flex-start", pt: "1" }); +const kpiGrid = css({ + display: "flex", + flexDirection: "column", + gap: "2", + w: "[220px]", +}); + +export const E2EWhatIf = ({ + graph, + timeRange, + onCollapse, + onStepDrill, + activeSegments, + onSegmentToggle, + activeRoute, + onActiveRouteChange, +}: E2EWhatIfProps) => { + const { waccRate, storageCost } = useCostParams(); + const { excludeOutliers } = useOutlierSetting(); + + const setActiveRoute = onActiveRouteChange; + // Levers store CAP days: missing entries or caps at the step's max mean + // uncapped (no change). Moving a lever left picks progressively stricter + // percentile caps. See whatif.ts header for full semantics. + const [capLevers, setCapLevers] = useState>({}); + const [showAll, setShowAll] = useState(false); + + const batches = useMemo( + () => graph.batch_timelines?.batches ?? [], + [graph.batch_timelines], + ); + + const leverDefs = useMemo( + () => + selectTopLevers(graph.nodes, batches, activeRoute || null, { + maxN: showAll ? 16 : MAX_VISIBLE_LEVERS, + activeSegments, + }), + [graph.nodes, batches, activeRoute, showAll, activeSegments], + ); + + const windowMonths = timeRange === "3m" ? 3 : timeRange === "6m" ? 6 : 12; + + const simulation = useMemo( + () => + aggregateSimulation( + graph.nodes, + batches, + capLevers, + leverDefs, + activeRoute || null, + { waccRate, storageCost }, + { windowMonths, activeSegments, excludeOutliers }, + ), + [ + graph.nodes, + batches, + capLevers, + leverDefs, + activeRoute, + waccRate, + storageCost, + windowMonths, + activeSegments, + excludeOutliers, + ], + ); + + const handleLeverChange = useCallback((stepId: string, value: number) => { + setCapLevers((prev) => ({ ...prev, [stepId]: value })); + }, []); + + const handleReset = useCallback(() => { + setCapLevers({}); + }, []); + + const hasActiveLevers = leverDefs.some((line) => { + return isCapActive(line, capLevers[line.stepId]); + }); + + const coverage = graph.batch_timelines?.coverage; + const coverageByRoute = graph.batch_timelines?.coverage_by_route; + const rangeLabel = `last ${windowMonths} months`; + + return ( +
+ {/* Shared header (route selector + collapse chevron). */} +
+ +
+ +
+ {/* Left: waterfall */} +
+ + +
+ Pre-production held constant.{" "} + Procurement and raw-material dwell sit before Production Start and + are not simulated here. Use the per-step cost calculator for + inventory-driven savings on those steps. +
+
+ + {/* Middle: levers */} +
+
+

Simulation levers

+ +
+
+ {leverDefs.length === 0 && ( +
+ No ranked step data available for this route. Try regenerating + data or selecting a different route. +
+ )} + {leverDefs.map((lever) => ( + handleLeverChange(lever.stepId, value)} + onDrill={() => onStepDrill(lever.stepId)} + nodes={graph.nodes} + /> + ))} + {leverDefs.length >= MAX_VISIBLE_LEVERS && !showAll && ( + + )} + {showAll && ( + + )} +
+
+ + {/* Right: KPIs */} +
+

Simulated impact

+
+ + + + + 0 + ? `${simulation.batchesAffected}/${simulation.batchesTotal} batches` + : undefined + } + success={ + simulation.costSavingAnnualised != null && + simulation.costSavingAnnualised > 0 + } + /> +
+
+
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/binding-lever.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/binding-lever.tsx new file mode 100644 index 00000000000..342beb3b6b5 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/binding-lever.tsx @@ -0,0 +1,282 @@ +import { Icon } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { formatNumber } from "../../../shared/cost"; +import { + capCheckpointsFor, + defaultCapDays, + formatNextBottleneck, + isCapActive, + meanObservedCapReduction, + type LeverDefinition, +} from "../whatif"; + +import type { GraphData } from "../../../shared/types"; + +const card = css({ + bg: "bgSolid.min", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + p: "3", + display: "flex", + flexDirection: "column", + gap: "2", +}); +const headRow = css({ + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", + gap: "2", +}); +const headMain = css({ minW: "0", flex: "1" }); +const leverLabel = css({ + textStyle: "sm", + fontWeight: "medium", + color: "fg.heading", + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap", +}); +const metaRow = css({ + textStyle: "xs", + color: "fg.subtle", + mt: "0.5", + display: "flex", + alignItems: "center", + gap: "2", + flexWrap: "wrap", +}); +const drillButton = css({ + color: "fg.subtle", + flexShrink: 0, + cursor: "pointer", + _hover: { color: "fg.heading" }, +}); +const sliderStack = css({ + display: "flex", + flexDirection: "column", + gap: "1.5", +}); +const checkpointRow = css({ + display: "grid", + gridTemplateColumns: "[repeat(6, minmax(0, 1fr))]", + gap: "1", +}); +const checkpointButtonBase = css({ + px: "1.5", + py: "1", + borderRadius: "md", + borderWidth: "1px", + borderStyle: "solid", + cursor: "pointer", + display: "flex", + flexDirection: "column", + alignItems: "center", + gap: "0.5", + minW: "0", + transition: "colors", +}); +const checkpointButtonActive = css({ + bg: "bgSolid.min", + borderColor: "fg.muted", + color: "fg.heading", +}); +const checkpointButtonInactive = css({ + bg: "bg.subtle", + borderColor: "bd.subtle", + color: "fg.subtle", + _hover: { color: "fg.muted", borderColor: "bd.subtle" }, +}); +const checkpointLabel = css({ + textStyle: "xxs", + fontWeight: "medium", + lineHeight: "none", +}); +const checkpointValue = css({ + textStyle: "xxs", + fontVariantNumeric: "tabular-nums", + lineHeight: "none", +}); +const pastBottleneck = css({ + color: "status.error.fg.body", + textStyle: "xxs", + flexShrink: 0, +}); +const effectiveRow = css({ textStyle: "xxs", color: "fg.subtle" }); +const staleRecipeBadge = css({ + display: "inline-flex", + alignItems: "center", + borderRadius: "sm", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "status.warning.bd.subtle", + bg: "status.warning.bg.subtle", + color: "status.warning.fg.body", + px: "1", + py: "[1px]", + textStyle: "xxs", + fontWeight: "medium", + cursor: "help", +}); + +interface BindingLeverProps { + lever: LeverDefinition; + /** Current cap in days. Missing/Max means uncapped. */ + capDays?: number; + onChange: (v: number) => void; + onDrill: () => void; + nodes: GraphData["nodes"]; +} + +export const BindingLever = ({ + lever, + capDays, + onChange, + onDrill, + nodes, +}: BindingLeverProps) => { + const node = nodes.find((count) => count.id === lever.stepId); + const selectedCap = capDays ?? defaultCapDays(lever); + const activeCap = isCapActive(lever, selectedCap); + const tailReduction = activeCap + ? meanObservedCapReduction(node, selectedCap) + : 0; + const beyondNextBottleneck = + activeCap && + lever.nextBottleneckDays != null && + lever.nextBottleneckDays > 0 && + tailReduction > lever.nextBottleneckDays; + const shortenedCount = activeCap + ? (node?.observations ?? []).filter( + (observation) => + typeof observation.value === "number" && + Number.isFinite(observation.value) && + observation.value > selectedCap, + ).length + : 0; + const observedCount = node?.observations?.length ?? 0; + + const checkpoints = capCheckpointsFor(lever); + const selectedCheckpoint = !activeCap + ? checkpoints.find((column) => column.key === "max") + : checkpoints.find( + (column) => + column.key !== "max" && Math.abs(column.capDays - selectedCap) < 0.5, + ); + + return ( +
+
+
+
+ {lever.label} +
+
+ + {formatNumber(lever.median, { maximumFractionDigits: 0 })}d median + {" / "} + {formatNumber(lever.mean, { maximumFractionDigits: 0 })}d mean + + {lever.inCurrentRecipe === false && ( + + Not in current recipe + + )} + {lever.nextBottleneckDays != null && + lever.nextBottleneckDays > 0 && + (() => { + const nb = formatNextBottleneck(lever.nextBottleneckChains); + const daysText = `${formatNumber(lever.nextBottleneckDays, { maximumFractionDigits: 0 })}d to next bottleneck`; + if (!nb) { + return {daysText}; + } + // Tooltip carries the full top-3 breakdown for inspection; + // visible text is the compact confident/mixed form. + const tooltip = lever.nextBottleneckChains + ?.map( + (column) => + `${column.label} (${Math.round(column.share * 100)}%)`, + ) + .join(" / "); + return ( + + {daysText} ({nb.text}) + + ); + })()} +
+
+ +
+ +
+
+ {checkpoints.map((checkpoint) => { + const selected = checkpoint.key === selectedCheckpoint?.key; + return ( + + ); + })} +
+ +
+ {activeCap + ? selectedCheckpoint?.key === "zero" + ? "Step is excluded from the simulated timeline" + : `Durations above ${formatNumber(selectedCap, { maximumFractionDigits: 0 })}d are capped` + : "Max selected -- no cap applied"} + {activeCap && observedCount > 0 && ( + <> + {" · "} + {formatNumber(shortenedCount)} / {formatNumber(observedCount)}{" "} + observations shortened + + )} + {beyondNextBottleneck && ( + <> + {" · "} + past next bottleneck + + )} +
+
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/caveats.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/caveats.ts new file mode 100644 index 00000000000..64deb9cdde3 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/caveats.ts @@ -0,0 +1,166 @@ +import { + formatNextBottleneck, + isCapActive, + meanObservedCapReduction, + type LeverDefinition, +} from "../whatif"; + +import type { GraphNode } from "../../../shared/types"; + +export type CaveatSeverity = "info" | "warning"; + +export interface Caveat { + id: string; + severity: CaveatSeverity; + label: string; + detail: string; +} + +interface CaveatInputs { + /** Map of step_id -> selected cap days. Missing/Max means uncapped. */ + capLevers: Record; + leverDefs: LeverDefinition[]; + nodes: GraphNode[]; +} + +/** + * Generate the contextual caveats to render below the KPI tiles, based on + * which levers the user has activated (i.e. selected a cap below Max). + * + * Each rule reads the active lever values + step metadata. Rules are + * deliberately concrete and conservative -- the goal is to keep the tool + * from over-promising for the cases we know are fragile (campaign + * bundling, non-binding parallel paths, next-bottleneck exceedance). + */ +export function buildWhatIfCaveats({ + capLevers, + leverDefs, + nodes, +}: CaveatInputs): Caveat[] { + const caveats: Caveat[] = []; + const nodeById = new Map(nodes.map((count) => [count.id, count])); + + // A lever is active when it caps durations below the step max. + const activeLevers = leverDefs.filter((line) => { + return isCapActive(line, capLevers[line.stepId]); + }); + + if (activeLevers.length === 0) { + return caveats; + } + + for (const lever of activeLevers) { + const capDays = capLevers[lever.stepId]; + const meanTailReduction = meanObservedCapReduction( + nodeById.get(lever.stepId), + capDays, + ); + + // 1. Bulk shipping cadence: post-QA dwell caps only realise if + // the dispatch cadence itself shifts. We fire on activation rather + // than at an arbitrary threshold -- the cadence dynamic exists at + // any cap level, varies by product/route/make-strategy, and + // is something the user should always be aware of when touching + // these levers. + if (lever.stepType === "post_qa_ship") { + caveats.push({ + id: `qa-cadence-${lever.stepId}`, + severity: "info", + label: "Bulk shipping cadence", + detail: `Realising caps on "${lever.label}" may depend on shipping cadence/batching -- shipments often leave in campaigns, so trimming long dwell observations may not materialise unless dispatch frequency itself changes. Varies by product, route, and make-strategy.`, + }); + } + + // 2. Next-bottleneck exceeded: once the cap's mean tail reduction is + // larger than the binding-chain headroom, another chain takes over + // and additional tail trimming on this step alone stops helping. + if ( + lever.nextBottleneckDays != null && + lever.nextBottleneckDays > 0 && + meanTailReduction > lever.nextBottleneckDays + ) { + const nb = formatNextBottleneck(lever.nextBottleneckChains); + const days = Math.round(lever.nextBottleneckDays); + const tailDays = Math.round(meanTailReduction); + let detail: string; + if (nb?.mode === "single") { + detail = `"${lever.label}" cap trims about ${tailDays}d of tail duration on average, beyond the ${days}d next-bottleneck headroom -- ${nb.text} chain becomes binding instead. Further capping on this step alone won't help unless you also tackle the next chain.`; + } else if (nb?.mode === "mixed") { + const phrased = nb.entries + .map( + (event) => + `${event.label} (${Math.round(event.share * 100)}% of binding batches)`, + ) + .join(" or "); + detail = `"${lever.label}" cap trims about ${tailDays}d of tail duration on average, beyond the ${days}d next-bottleneck headroom -- the next binding chain is typically ${phrased}. Further capping on this step alone won't help unless you also tackle the next chain.`; + } else { + detail = `"${lever.label}" cap trims about ${tailDays}d of tail duration on average, beyond the ${days}d next-bottleneck headroom -- further capping on this step alone yields no additional E2E saving until you also reduce the next-binding step.`; + } + caveats.push({ + id: `next-bottleneck-${lever.stepId}`, + severity: "info", + label: "Beyond next bottleneck", + detail, + }); + } + + // 3. Low binding share: capping a step that rarely binds is mostly + // inert unless paired with caps on the steps that do bind. + if ( + lever.bindingShare > 0 && + lever.bindingShare < 0.4 && + lever.stepType !== "post_qa_ship" && + lever.stepType !== "transit" && + lever.stepType !== "destination_dwell" && + lever.stepType !== "production" && + lever.stepType !== "qa_hold" + ) { + caveats.push({ + id: `low-binding-${lever.stepId}`, + severity: "info", + label: "Low binding share", + detail: `"${lever.label}" is binding for only ${Math.round(lever.bindingShare * 100)}% of batches. Most of the cap's value is offset by other paths still binding the E2E.`, + }); + } + } + + // 4. Multiple non-binding parallel upstream levers compounding + const lowBindUpstream = activeLevers.filter( + (line) => + line.bindingShare < 0.5 && + (line.stepType === "intermediate_dwell" || + line.stepType === "production"), + ); + if (lowBindUpstream.length >= 2) { + caveats.push({ + id: "multi-non-binding", + severity: "warning", + label: "Multiple non-binding parallel paths", + detail: + "Several upstream levers act on steps that rarely bind individually. They only compound the E2E saving once their combined capped tail mass changes the binding-chain length -- the curve is non-linear and the headline number is an upper bound.", + }); + } + + // 5. Production capacity caveat -- only relevant when the user is + // touching a step whose freed time would have to be re-absorbed by + // production scheduling (FG / upstream production runs, or + // intermediate dwell, where shorter dwell means an earlier + // downstream production order). Skip for purely post-production + // levers (QA hold, shipping, transit, destination dwell) where + // production-asset availability isn't the constraint. + const PROD_CAPACITY_TYPES = new Set([ + "production", + "intermediate_dwell", + ]); + if (activeLevers.some((line) => PROD_CAPACITY_TYPES.has(line.stepType))) { + caveats.push({ + id: "capacity-not-modelled", + severity: "info", + label: "Production capacity not modelled", + detail: + "Caps on production / intermediate-dwell steps assume freed time can be re-absorbed by the production schedule. No assumption is made about asset availability, campaign re-planning, or buffer rules.", + }); + } + + return caveats; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/what-if-kpis.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/what-if-kpis.tsx new file mode 100644 index 00000000000..dc2b6b5a1ec --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/e2e-what-if/what-if-kpis.tsx @@ -0,0 +1,110 @@ +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { formatNumber } from "../../../shared/cost"; + +import type { Caveat } from "./caveats"; + +const tile = css({ + bg: "bg.subtle", + borderRadius: "lg", + p: "2.5", + display: "flex", + flexDirection: "column", + gap: "1.5", +}); +const tileSuccess = css({ + bg: "status.success.bg.subtle", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "status.success.bd.subtle", +}); +const tileLabel = css({ + textStyle: "xs", + fontWeight: "medium", + color: "fg.muted", +}); +const tileValue = css({ + textStyle: "base", + fontWeight: "medium", + color: "fg.max", + fontVariantNumeric: "tabular-nums", + lineHeight: "[20px]", +}); +const tileFoot = css({ + textStyle: "xxs", + fontVariantNumeric: "tabular-nums", + display: "flex", + alignItems: "center", + justifyContent: "space-between", +}); +const deltaGood = css({ color: "status.success.fg.body" }); +const deltaMuted = css({ color: "fg.subtle" }); +const subtleText = css({ color: "fg.subtle" }); + +const chipBase = css({ + borderRadius: "md", + borderWidth: "1px", + borderStyle: "solid", + px: "2", + py: "1.5", + textStyle: "xs", + lineHeight: "snug", +}); +const chipWarning = css({ + bg: "status.error.bg.subtle", + color: "status.error.fg.body", + borderColor: "status.error.bd.subtle", +}); +const chipInfo = css({ + bg: "bg.subtle", + color: "fg.heading", + borderColor: "bd.subtle", +}); +const chipLabel = css({ fontWeight: "medium" }); +const chipDetail = css({ textStyle: "xxs", mt: "0.5", opacity: "0.9" }); + +export const KpiTile = ({ + label, + value, + subtle, + delta, + deltaUnit, + success, +}: { + label: string; + value: string; + subtle?: string; + delta?: number | null; + deltaUnit?: string; + success?: boolean; +}) => { + const deltaText = + delta != null && delta !== 0 + ? `${delta > 0 ? "+" : ""}${formatNumber(delta, { maximumFractionDigits: 1 })}${deltaUnit ?? ""}` + : null; + const deltaClass = delta != null && delta < 0 ? deltaGood : deltaMuted; + return ( +
+
{label}
+
{value}
+
+ {deltaText ? {deltaText} : } + {subtle && {subtle}} +
+
+ ); +}; + +export const CaveatChip = ({ caveat }: { caveat: Caveat }) => { + return ( +
+
{caveat.label}
+
{caveat.detail}
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph.tsx new file mode 100644 index 00000000000..dd1ca02dec1 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph.tsx @@ -0,0 +1,328 @@ +import { + ReactFlow, + Background, + Controls, + ControlButton, + Panel, + type Node, + type Edge, + type NodeTypes, + type ReactFlowInstance, + MarkerType, + useNodesState, + useEdgesState, +} from "@xyflow/react"; +import ELK, { type ElkNode } from "elkjs/lib/elk.bundled.js"; +import "@xyflow/react/dist/style.css"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + +import { Icon } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { StepNode } from "./process-graph/step-node"; + +import type { GraphData, GraphNode, GraphEdge } from "../../shared/types"; + +const nodeTypes: NodeTypes = { + stepNode: StepNode as unknown as NodeTypes[string], +}; + +const canvasShell = css({ + w: "full", + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bgSolid.min", +}); +const canvasFull = css({ h: "[100vh]" }); +const canvasNormal = css({ h: "full", minH: "[360px]" }); +const exitButton = css({ + bg: "[rgba(255,255,255,0.9)]", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + boxShadow: "sm", + borderRadius: "md", + px: "3", + py: "1.5", + textStyle: "xs", + fontWeight: "medium", + color: "fg.muted", + cursor: "pointer", + _hover: { bg: "bgSolid.min" }, +}); + +const NODE_WIDTH = 240; +const NODE_HEIGHT = 110; + +const elk = new ELK(); + +interface LayoutResult { + positions: Record; + minY: number; + maxY: number; +} + +async function computeLayout( + graphNodes: GraphNode[], + graphEdges: GraphEdge[], +): Promise { + const elkGraph: ElkNode = { + id: "root", + layoutOptions: { + "elk.algorithm": "elk.layered", + "elk.direction": "RIGHT", + "elk.spacing.nodeNode": "30", + "elk.layered.spacing.nodeNodeBetweenLayers": "80", + "elk.layered.crossingMinimization.strategy": "LAYER_SWEEP", + "elk.layered.nodePlacement.strategy": "NETWORK_SIMPLEX", + }, + children: graphNodes.map((gn) => ({ + id: gn.id, + width: NODE_WIDTH, + height: NODE_HEIGHT, + })), + edges: graphEdges.map((event, index) => ({ + id: `e-${index}`, + sources: [event.source], + targets: [event.target], + })), + }; + + const result = await elk.layout(elkGraph); + + const positions: Record = {}; + let minY = Number.POSITIVE_INFINITY; + let maxY = Number.NEGATIVE_INFINITY; + for (const child of result.children ?? []) { + const xValue = child.x ?? 0; + const yValue = child.y ?? 0; + positions[child.id] = { x: xValue, y: yValue }; + minY = Math.min(minY, yValue); + maxY = Math.max(maxY, yValue + NODE_HEIGHT); + } + + return { positions, minY, maxY }; +} + +function computeViewport(minY: number, maxY: number, containerH: number) { + const graphH = maxY - minY; + const zoom = Math.min(containerH / (graphH + 40), 1); + const scaledH = graphH * zoom; + return { + x: 10, + y: (containerH - scaledH) / 2 - minY * zoom, + zoom, + }; +} + +interface ProcessGraphProps { + graph: GraphData; + onStepClick: (stepId: string) => void; + timeRange?: string; +} + +export const ProcessGraph = ({ + graph, + onStepClick, + timeRange, +}: ProcessGraphProps) => { + const containerRef = useRef(null); + const rfRef = useRef(null); + const [isFullscreen, setIsFullscreen] = useState(false); + const [containerHeight, setContainerHeight] = useState(900); + + const [layout, setLayout] = useState(null); + + useEffect(() => { + let cancelled = false; + void computeLayout(graph.nodes, graph.edges).then((result) => { + if (!cancelled) { + setLayout(result); + } + }); + return () => { + cancelled = true; + }; + }, [graph]); + + const flowEdges: Edge[] = useMemo( + () => + graph.edges.map((event, index) => ({ + id: `e-${index}`, + source: event.source, + target: event.target, + type: "smoothstep", + animated: false, + style: { stroke: "#cbd5e1", strokeWidth: 1.5 }, + markerEnd: { + type: MarkerType.ArrowClosed, + color: "#cbd5e1", + width: 14, + height: 14, + }, + })), + [graph.edges], + ); + + const initialNodes: Node[] = useMemo(() => { + if (!layout) { + return []; + } + return graph.nodes.map((gn: GraphNode) => ({ + id: gn.id, + type: "stepNode", + position: layout.positions[gn.id] ?? { x: 0, y: 0 }, + data: { ...gn, onClick: onStepClick, timeRange }, + initialWidth: NODE_WIDTH, + initialHeight: NODE_HEIGHT, + })); + }, [graph.nodes, layout, onStepClick, timeRange]); + + const defaultViewport = useMemo( + () => + layout + ? computeViewport(layout.minY, layout.maxY, containerHeight) + : { x: 10, y: 10, zoom: 1 }, + [containerHeight, layout], + ); + + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); + const [edges, , onEdgesChange] = useEdgesState(flowEdges); + + useEffect(() => { + setNodes((prev) => { + const posMap = new Map(prev.map((count) => [count.id, count.position])); + return initialNodes.map((count) => ({ + ...count, + position: posMap.get(count.id) ?? count.position, + })); + }); + }, [initialNodes, setNodes]); + + useEffect(() => { + if (!layout || !rfRef.current) { + return; + } + const vp = computeViewport(layout.minY, layout.maxY, containerHeight); + void rfRef.current.setViewport(vp, { duration: 0 }); + }, [containerHeight, layout]); + + const onAutoLayout = useCallback(async () => { + const freshLayout = await computeLayout(graph.nodes, graph.edges); + setNodes((prev) => + prev.map((count) => ({ + ...count, + position: freshLayout.positions[count.id] ?? count.position, + })), + ); + const containerH = + containerRef.current?.getBoundingClientRect().height ?? 900; + const vp = computeViewport(freshLayout.minY, freshLayout.maxY, containerH); + void rfRef.current?.setViewport(vp, { duration: 300 }); + }, [graph, setNodes]); + + const onToggleFullscreen = useCallback(() => { + const el = containerRef.current; + if (!el) { + return; + } + if (!document.fullscreenElement) { + el.requestFullscreen().catch(() => {}); + } else { + document.exitFullscreen().catch(() => {}); + } + }, []); + + const onFullscreenChange = useCallback(() => { + setIsFullscreen(!!document.fullscreenElement); + }, []); + + const containerCallbackRef = useCallback( + (el: HTMLDivElement | null) => { + if (el) { + ( + containerRef as React.MutableRefObject + ).current = el; + el.addEventListener("fullscreenchange", onFullscreenChange); + } + }, + [onFullscreenChange], + ); + + useEffect(() => { + const el = containerRef.current; + if (!el) { + return; + } + + const updateHeight = () => { + const nextHeight = el.getBoundingClientRect().height; + if (nextHeight > 0) { + setContainerHeight(nextHeight); + } + }; + updateHeight(); + + const observer = new ResizeObserver(updateHeight); + observer.observe(el); + return () => observer.disconnect(); + }, []); + + const onInit = useCallback((instance: ReactFlowInstance) => { + rfRef.current = instance; + }, []); + + const onNodeClick = useCallback( + (_: React.MouseEvent, node: Node) => { + onStepClick(node.id); + }, + [onStepClick], + ); + + return ( +
+ + + + + + + + + + + {isFullscreen && ( + + + + )} + +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph/step-node.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph/step-node.tsx new file mode 100644 index 00000000000..c5d1334d217 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/process-graph/step-node.tsx @@ -0,0 +1,38 @@ +import { Handle, Position, type NodeProps } from "@xyflow/react"; +import { memo, type CSSProperties } from "react"; + +import { css } from "@hashintel/ds-helpers/css"; +import { token } from "@hashintel/ds-helpers/tokens"; + +import { StepCard } from "../shared/step-card"; + +import type { GraphNode } from "../../../shared/types"; + +type StepNodeData = GraphNode & { + onClick?: (id: string) => void; + timeRange?: string; +}; + +const nodeWrap = css({ w: "[240px]" }); +const handleStyle: CSSProperties = { + background: token.var("colors.bd.subtle"), + width: 8, + height: 8, + border: "1px solid #ffffff", +}; + +const StepNodeComponent = ({ data }: NodeProps & { data: StepNodeData }) => { + return ( +
+ + + data.onClick?.(data.id)} + timeRange={data.timeRange} + /> +
+ ); +}; + +export const StepNode = memo(StepNodeComponent); diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/recompute-batch-timelines.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/recompute-batch-timelines.ts new file mode 100644 index 00000000000..83622b9043a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/recompute-batch-timelines.ts @@ -0,0 +1,209 @@ +import { computeIqrFences } from "../../shared/outlier-selection/iqr"; + +import type { + BatchRow, + BatchSegmentKey, + BatchTimelineSegment, + BatchTimelines, + PipelineSummary, + StepType, +} from "../../shared/types"; + +/** + * Summary statistics for one batch segment over a filtered batch set. + * Uses nearest-rank percentiles (no interpolation/rounding) so the pipeline + * waterfall matches the backend's batch-timeline numbers. When `excludeOutliers` + * is set, the segment's per-batch values are first trimmed with the shared + * Tukey 1.5x IQR rule (same definition as the node/step series) so the + * waterfall + E2E totals honour the outlier toggle. + */ +function segStats( + batches: BatchRow[], + key: BatchSegmentKey, + excludeOutliers: boolean, +): BatchTimelineSegment | null { + let vals = batches + .map((right) => right[key]) + .filter( + (value): value is number => value != null && value >= 0 && value <= 730, + ); + if (vals.length === 0) { + return null; + } + if (excludeOutliers) { + const fences = computeIqrFences(vals); + if (fences) { + vals = vals.filter( + (value) => value >= fences.lower && value <= fences.upper, + ); + } + if (vals.length === 0) { + return null; + } + } + vals.sort((left, right) => left - right); + const mean = vals.reduce((step, value) => step + value, 0) / vals.length; + const midpoint = Math.floor(vals.length / 2); + const upper = vals[midpoint]; + if (upper === undefined) { + throw new Error("Segment statistics were missing a midpoint value"); + } + const median = + vals.length % 2 === 0 + ? (() => { + const lower = vals[midpoint - 1]; + if (lower === undefined) { + throw new Error( + "Segment statistics were missing a lower midpoint value", + ); + } + return (lower + upper) / 2; + })() + : upper; + const p25 = vals[Math.floor(vals.length * 0.25)]; + const p75 = vals[Math.floor(vals.length * 0.75)]; + if (p25 === undefined || p75 === undefined) { + throw new Error("Segment statistics percentile value missing"); + } + return { label: "", mean, median, p25, p75, n: vals.length }; +} + +/** Pipeline stages in display order: segment key, label, and step type. */ +const SEG_DEFS: Array<[BatchSegmentKey, string, StepType]> = [ + [ + "seg_proc_to_prodstart", + "Procurement \u2192 Production Start", + "procurement", + ], + + [ + "seg_prodstart_to_prodfinish", + "Production Start \u2192 Production Finish", + "production", + ], + + ["seg_prodfinish_to_qa", "Production Finish \u2192 QA Release", "qa_hold"], + ["seg_qa_to_customer", "QA Release \u2192 Customer", "transit"], +]; + +/** Every segment recomputed for the segments map (includes the two totals). */ +const RECOMPUTE_SEG_DEFS: Array<[BatchSegmentKey, string]> = [ + ["seg_proc_to_prodstart", "Procurement \u2192 Production Start"], + ["seg_prodstart_to_prodfinish", "Production Start \u2192 Production Finish"], + ["seg_prodfinish_to_qa", "Production Finish \u2192 QA Release"], + ["seg_qa_to_customer", "QA Release \u2192 Customer"], + ["total_days", "Total (GR to Delivery)"], + ["total_from_po", "Total (PO to Delivery)"], +]; + +/** + * Recompute batch-timeline segments and the derived per-route pipeline summary + * from a date-filtered batch set, preserving the original route labels and + * detail-column metadata. + */ +export function recomputeBatchTimelines( + filteredBatches: BatchRow[], + original: BatchTimelines, + excludeOutliers = false, +): { timelines: BatchTimelines; pipeline: Record } { + const segments: Record = {}; + for (const [key, label] of RECOMPUTE_SEG_DEFS) { + const step = segStats(filteredBatches, key, excludeOutliers); + if (step) { + segments[key] = { ...step, label }; + } + } + + const tracedCount = filteredBatches.filter( + (right) => + right.earliest_gr_date != null || right.earliest_production_start != null, + ).length; + + // Per-route breakdown + const perRoute: Record< + string, + { label: string; segments: Record } + > = {}; + const coverageByRoute: Record = {}; + const byRoute = new Map(); + for (const right of filteredBatches) { + const row = right.route; + if (!row) { + continue; + } + const existing = byRoute.get(row); + if (existing) { + existing.push(right); + } else { + byRoute.set(row, [right]); + } + } + for (const [route, rows] of byRoute) { + const routeSegs: Record = {}; + for (const [key, label] of RECOMPUTE_SEG_DEFS.filter( + ([key2]) => key2 !== "total_from_po", + )) { + const step = segStats(rows, key, excludeOutliers); + if (step) { + routeSegs[key] = { ...step, label }; + } + } + const origRoute = original.per_route[route]; + perRoute[route] = { label: origRoute?.label ?? route, segments: routeSegs }; + coverageByRoute[route] = { + traced: rows.filter( + (right) => + right.earliest_gr_date != null || + right.earliest_production_start != null, + ).length, + total: rows.length, + }; + } + + // Build pipeline summary from filtered data + const pipeline: Record = {}; + for (const [routeCode, routeData] of Object.entries(perRoute)) { + const stages = []; + let totalMean = 0; + let totalMedian = 0; + for (const [segId, segLabel, segType] of SEG_DEFS) { + const seg = routeData.segments[segId]; + if (!seg) { + continue; + } + stages.push({ + id: segId, + label: segLabel, + type: segType, + mean: seg.mean, + median: seg.median, + pct_of_total: 0, + }); + totalMean += seg.mean; + totalMedian += seg.median; + } + if (totalMean > 0) { + for (const step of stages) { + step.pct_of_total = (step.mean / totalMean) * 100; + } + } + pipeline[routeCode] = { + label: routeData.label, + stages, + total_mean: totalMean, + total_median: totalMedian, + }; + } + + return { + timelines: { + batches: filteredBatches, + segments, + per_route: perRoute, + coverage: { traced: tracedCount, total: filteredBatches.length }, + coverage_by_route: coverageByRoute, + detail_columns: original.detail_columns, + }, + pipeline, + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/category-icon.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/category-icon.tsx new file mode 100644 index 00000000000..eea5d4bd101 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/category-icon.tsx @@ -0,0 +1,155 @@ +import type { CategoryIcon as CategoryIconType } from "../../../shared/categories"; + +interface CategoryIconProps { + icon: CategoryIconType; + size?: number; + color?: string; + className?: string; +} + +export const CategoryIcon = ({ + icon, + size = 12, + color = "currentColor", + className, +}: CategoryIconProps) => { + const props = { + width: size, + height: size, + viewBox: "0 0 14 14", + fill: "none", + className, + "aria-hidden": true as const, + }; + + switch (icon) { + case "puzzle": + // The glyph only occupies the centre ~half of the 0 0 14 14 box, so it + // renders visibly smaller than the other category icons. Crop the + // viewBox tight around it so it fills the frame at the same weight. + return ( + + Puzzle + + + ); + + case "clock": + return ( + + Clock + + + + ); + + case "blocks": + return ( + + Blocks + + + + + ); + + case "search-check": + return ( + + Search check + + + + + ); + + case "truck": + return ( + + Truck + + + + + + ); + } +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/pipeline-header.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/pipeline-header.tsx new file mode 100644 index 00000000000..ea4c8632402 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/product/shared/pipeline-header.tsx @@ -0,0 +1,174 @@ +import { Button, Select } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { formatNumber } from "../../../shared/cost"; +import { shortPlantLabel } from "../../../shared/plant-label"; +import { useRegistry } from "../../../shared/registry-context"; + +import type { PipelineSummary } from "../../../shared/types"; + +interface PipelineHeaderProps { + summaries: Record; + /** Global batch-trace coverage (fallback when no per-route entry exists). */ + coverage?: { traced: number; total: number }; + /** Per-route coverage keyed by route code; used to scope the count to the + * selected destination. Falls back to `coverage` when absent. */ + coverageByRoute?: Record; + /** Human label for the active analysis window, e.g. "last 12 months". */ + rangeLabel?: string; + activeRoute: string; + onActiveRouteChange: (route: string) => void; + /** Larger title for the expanded what-if panel. */ + expanded?: boolean; + /** Render an expand-up chevron; fires onExpand on click. */ + onExpand?: () => void; + /** Render a collapse-down chevron; fires onCollapse on click. */ + onCollapse?: () => void; +} + +const row = css({ + display: "flex", + alignItems: "center", + justifyContent: "space-between", + flexWrap: "wrap", + gap: "2", +}); +const titleGroup = css({ display: "flex", alignItems: "center", gap: "3" }); +const titleBase = css({ fontWeight: "medium", color: "fg.heading" }); +const titleLg = css({ textStyle: "lg" }); +const titleMd = css({ textStyle: "base" }); +const coverageText = css({ textStyle: "xs", color: "fg.subtle" }); +const controls = css({ display: "flex", alignItems: "center", gap: "2" }); +const selectWidth = css({ w: "[13rem]" }); +const selectWidthExpanded = css({ w: "[min(28rem,48vw)]" }); +const singleLabel = css({ + textStyle: "sm", + fontWeight: "medium", + color: "fg.heading", +}); + +/** + * Shared header for the end-to-end pipeline (title + coverage + route picker + + * optional expand/collapse chevron), used by both the collapsed waterfall in + * `Overview` and the expanded `E2EWhatIf` panel so there is one header + * implementation rather than two near-identical copies. + */ +export const PipelineHeader = ({ + summaries, + coverage, + coverageByRoute, + rangeLabel, + activeRoute, + onActiveRouteChange, + expanded = false, + onExpand, + onCollapse, +}: PipelineHeaderProps) => { + const { sites } = useRegistry(); + const routes = Object.keys(summaries); + const summary = summaries[activeRoute]; + + // Resolve a friendly destination name for a route. The route key for + // non-direct routes is a bare destination-hub code. Prefer a registered + // site name, then a trimmed form of the summary's resolved label (the + // generator ships the full plant name; `shortPlantLabel` strips generic + // corporate boilerplate), and only fall back to the bare code as a last + // resort. + const destinationName = (key: string): string => { + const named = sites.find((step) => step.slug === key)?.name; + if (named) { + return named; + } + const label = summaries[key]?.label; + if (label && label.toLowerCase() !== key.toLowerCase()) { + return shortPlantLabel(key, label); + } + return key.toUpperCase(); + }; + + // Full, untrimmed destination label (kept in the data) for tooltips. + const destinationFullLabel = (key: string): string | undefined => { + if (key === "direct") { + return undefined; + } + const label = summaries[key]?.label; + return label && label.toLowerCase() !== key.toLowerCase() + ? label + : undefined; + }; + + const routeText = (key: string): string => { + if (key === "direct") { + return summaries[key]?.label ?? "Direct"; + } + return `Via ${destinationName(key)}`; + }; + + // Coverage scoped to the selected destination, with a clear window suffix, + // e.g. "N of M batches to traced · last 12 months". + const cov = coverageByRoute?.[activeRoute] ?? coverage; + const coverageLabel = (() => { + if (!cov || cov.total <= 0) { + return null; + } + const counts = `${formatNumber(cov.traced)} of ${formatNumber(cov.total)}`; + const scope = + activeRoute === "direct" + ? `${counts} direct batches traced` + : `${counts} batches to ${destinationName(activeRoute)} traced`; + return rangeLabel ? `${scope} \u00b7 ${rangeLabel}` : scope; + })(); + + return ( +
+
+

+ End-to-End Pipeline +

+ {coverageLabel && ( + + {coverageLabel} + + )} +
+
+ {routes.length > 1 ? ( + setShowRead(event.target.checked)} + /> + Show read + +
+
+
+ + + + + + + + + + + +
TypeOpportunityImpactSampleActions
+ {grouped.map((section) => ( +
+
+ +
+ {!collapsedSections.has(section.id) && ( + + + + {section.opportunities.map((opportunity) => { + const status = statuses[opportunity.id]; + return ( + onRowClick(opportunity.node)} + onKeyDown={(event) => { + if (event.key === "Enter") { + onRowClick(opportunity.node); + } + }} + > + + + + + + + ); + })} + +
+ + {opportunity.typeLabel} + + +
+ + {opportunity.title} + + +
+
+ + {opportunity.impactValue} + +
+ {opportunity.impactLabel} +
+
+ + + {sampleBadgeLabel(opportunity.confidenceLabel)} + + + +
+ {opportunity.briefHref && ( + event.stopPropagation()} + /> + )} + { + event.stopPropagation(); + onStatus(opportunity.node, opportunity.title); + }} + /> + + : + } + onClick={(event) => { + event.stopPropagation(); + if (status?.read) { + onMarkUnread(opportunity.id); + } else { + onMarkRead(opportunity.id); + } + }} + > + {status?.read ? "Mark unread" : "Mark read"} + +
+
+ )} +
+ ))} + {visibleCount === 0 && ( + + + + + + +
+ {opportunities.length === 0 + ? "No opportunities match the current filters." + : "No unread opportunities. Enable “Show read” to review completed items."} +
+ )} +
+ + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.test.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.test.ts new file mode 100644 index 00000000000..c265f693fba --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.test.ts @@ -0,0 +1,198 @@ +import { describe, expect, it } from "vitest"; + +import { + buildSiteOpportunities, + normalizeStatusOption, + statusCommentRequired, +} from "./opportunities"; + +import type { StepStats } from "../../shared/types"; +import type { DwellRow, PlanningRow } from "./shared/row-types"; + +const zeroStats: StepStats = { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, +}; + +function stats(overrides: Partial): StepStats { + return { ...zeroStats, ...overrides }; +} + +function dwell(overrides: Partial): DwellRow { + return { + id: "dwell", + label: "Dwell step", + type: "intermediate_dwell", + material: null, + plant: "PL-A", + stats: stats({ n: 20, median: 10, p95: 18 }), + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: { unit_price: 100, currency: "EUR" }, + products: [{ id: "p1", name: "Product 1" }], + periodCost: 1000, + costTrendPct: null, + previousPeriodCost: null, + previousCostN: 0, + trendPct: null, + previousValue: null, + previousTrendN: 0, + ...overrides, + }; +} + +function planning(overrides: Partial): PlanningRow { + return { + id: "plan", + label: "Planning step", + type: "production", + material: null, + plant: "PL-A", + stats: stats({ n: 20, median: 12, p95: 24 }), + plan: 10, + plan_note: null, + pct_exceeding_plan: 30, + cost: null, + products: [{ id: "p1", name: "Product 1" }], + deviationPct: 20, + trendPct: null, + previousValue: null, + previousTrendN: 0, + ...overrides, + }; +} + +describe("buildSiteOpportunities", () => { + const build = (input: { + dwellRows?: DwellRow[]; + planningRows?: PlanningRow[]; + }) => + buildSiteOpportunities({ + siteId: "site-a", + dwellRows: input.dwellRows ?? [], + planningRows: input.planningRows ?? [], + timeRange: "12m", + currency: "EUR", + briefHref: (type, node, kind) => + `/brief/${type}/${node.id}${kind ? `?op=${kind}` : ""}`, + }); + + it("creates dwell opportunities only above the dwell-days and 5k cost thresholds", () => { + const opportunities = build({ + dwellRows: [ + dwell({ + id: "high", + stats: stats({ n: 20, median: 8, p95: 20 }), + periodCost: 6000, + }), + dwell({ + id: "short", + stats: stats({ n: 20, median: 6, p95: 7 }), + periodCost: 9000, + }), + dwell({ + id: "below-min", + stats: stats({ n: 20, median: 12, p95: 20 }), + periodCost: 4000, + }), + dwell({ + id: "free", + stats: stats({ n: 20, median: 12, p95: 20 }), + periodCost: 0, + }), + ], + }); + + expect(opportunities.map((opportunity) => opportunity.id)).toEqual([ + "site-a::dwell_cost::12m::high-p1", + ]); + const opportunity = opportunities[0]; + expect(opportunity).toBeDefined(); + expect(opportunity!.briefHref).toBe("/brief/dwell/high?op=dwell_cost"); + expect(opportunity!.confidenceLabel).toBe("Good sample"); + }); + + it("classifies planning over and under opportunities using P95 vs plan", () => { + const opportunities = build({ + planningRows: [ + planning({ + id: "over", + plan: 10, + stats: stats({ n: 20, median: 8, p95: 11.5 }), + }), + planning({ + id: "under", + plan: 10, + stats: stats({ n: 20, median: 6, p95: 8.5 }), + }), + planning({ + id: "ok", + plan: 10, + stats: stats({ n: 20, median: 9, p95: 10.5 }), + }), + ], + }); + + expect(opportunities.map((opportunity) => opportunity.kind).sort()).toEqual( + ["planning_over", "planning_under"], + ); + expect( + opportunities.find((opportunity) => opportunity.kind === "planning_over") + ?.briefHref, + ).toBe("/brief/planning/over?op=planning_over"); + expect( + opportunities.find((opportunity) => opportunity.kind === "planning_over") + ?.currentSampleN, + ).toBe(20); + }); + + it("uses current sample size for planning confidence", () => { + const opportunities = build({ + planningRows: [ + planning({ + id: "plan-prev-low", + previousTrendN: 1, + plan: 10, + stats: stats({ n: 20, median: 8, p95: 13 }), + }), + ], + }); + + expect( + opportunities.find((opportunity) => opportunity.kind === "planning_over") + ?.confidenceLabel, + ).toBe("Good sample"); + }); +}); + +describe("status helpers", () => { + it("maps previous category aliases to status categories", () => { + expect(normalizeStatusOption("investigating")).toBe( + "investigation_started", + ); + expect(normalizeStatusOption("concluded")).toBe("investigation_concluded"); + expect(normalizeStatusOption("not_feasible")).toBe("rejected_infeasible"); + expect(normalizeStatusOption("data_issue")).toBe("rejected_data_issue"); + expect(normalizeStatusOption("investigation_update")).toBe( + "investigation_update", + ); + expect(normalizeStatusOption("unknown")).toBe("investigation_started"); + }); + + it("requires comments except for investigation started", () => { + expect(statusCommentRequired("investigation_started")).toBe(false); + expect(statusCommentRequired("investigation_update")).toBe(true); + expect(statusCommentRequired("investigation_concluded")).toBe(true); + expect(statusCommentRequired("rejected_infeasible")).toBe(true); + expect(statusCommentRequired("rejected_data_issue")).toBe(true); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.ts new file mode 100644 index 00000000000..e396939ffc5 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/opportunities.ts @@ -0,0 +1,293 @@ +import { isDwellType } from "../../shared/categories"; +import { formatCost, formatNumber } from "../../shared/cost"; +import { LOW_SAMPLE_N } from "./shared/row-types"; +import { siteNodeKey } from "./shared/site-node-key"; + +import type { TimeRange } from "../../shared/time-range"; +import type { SiteNode } from "../../shared/types"; +import type { DwellRow, PlanningRow } from "./shared/row-types"; + +export type OpportunityKind = "dwell_cost" | "planning_over" | "planning_under"; + +export type StatusOption = + | "investigation_started" + | "investigation_update" + | "investigation_concluded" + | "rejected_infeasible" + | "rejected_data_issue"; + +export interface OpportunityStatus { + read: boolean; + readAt?: string; +} + +export type OpportunityStatuses = Record; + +/** A single status update left against a step/node. */ +export interface StatusEntry { + /** ISO timestamp the status was saved. */ + at: string; + /** Author (dummy in this SPA; populated for real later). */ + user: string; + category: StatusOption; + text: string; +} + +/** Status history keyed by {@link statusKey} (step/node + opportunity type). */ +export type StatusStore = Record; + +export interface OpportunityStatusActions { + onMarkRead: (id: string) => void; + onMarkUnread: (id: string) => void; + onSaveStatus: ( + key: string, + status: { category: StatusOption; text: string }, + ) => void; +} + +/** + * Stable key for status aggregation: site + opportunity type (dwell vs + * planning, derived from the node) + node identity. A node has a single type, + * so this aggregates all status history for that step regardless of which + * opportunity (dwell / planning / trend) the status was left from, and is independent of + * the time range / measure (unlike the opportunity id). + */ +export function statusKey(siteId: string, node: SiteNode): string { + const type = isDwellType(node.type) ? "dwell" : "planning"; + return [siteId, type, siteNodeKey(node)].join("::"); +} + +export interface SiteOpportunity { + id: string; + kind: OpportunityKind; + siteId: string; + productId: string; + stepId: string; + node: SiteNode; + title: string; + products: Array<{ id: string; name: string }>; + typeLabel: string; + impactLabel: string; + impactValue: string; + impactTone: "danger" | "success" | "neutral"; + evidence: string; + sampleLabel: string; + currentSampleN: number; + previousSampleN?: number | null; + confidenceLabel: string; + score: number; + briefHref?: string; +} + +export interface BuildSiteOpportunitiesInput { + siteId: string; + dwellRows: DwellRow[]; + planningRows: PlanningRow[]; + timeRange: TimeRange; + currency: string | null; + briefHref: ( + type: "dwell" | "planning", + node: SiteNode, + kind?: OpportunityKind, + ) => string; +} + +const DWELL_DAYS_CUTOFF = 7; +// Minimum annualised carrying cost (site currency, treated as the CHF-equivalent +// floor) for a dwell-cost opportunity: below this the saving isn't worth surfacing. +const DWELL_MIN_PERIOD_COST = 5000; +const PLANNING_RATIO_THRESHOLD = 0.1; +export const STATUS_OPTIONS: Array<{ value: StatusOption; label: string }> = [ + { value: "investigation_started", label: "Investigation started" }, + { value: "investigation_update", label: "Investigation update" }, + { value: "investigation_concluded", label: "Investigation concluded" }, + { value: "rejected_infeasible", label: "Rejected (infeasible)" }, + { value: "rejected_data_issue", label: "Rejected (data issue)" }, +]; + +export function normalizeStatusOption(value: unknown): StatusOption { + if (value === "investigating") { + return "investigation_started"; + } + if (value === "concluded") { + return "investigation_concluded"; + } + if (value === "not_feasible") { + return "rejected_infeasible"; + } + if (value === "data_issue") { + return "rejected_data_issue"; + } + if (STATUS_OPTIONS.some((option) => option.value === value)) { + return value as StatusOption; + } + return "investigation_started"; +} + +export function statusCommentRequired(category: StatusOption): boolean { + return category !== "investigation_started"; +} + +function opportunityId( + siteId: string, + kind: OpportunityKind, + node: SiteNode, + context: string, +): string { + return [siteId, kind, context, siteNodeKey(node)].join("::"); +} + +function confidenceLabel( + currentN: number, + previousN: number | null | undefined, + hasRequiredData: boolean, + includePrevious: boolean, +): string { + if (!hasRequiredData) { + return "Low sample"; + } + if ( + currentN < LOW_SAMPLE_N || + (includePrevious && + previousN != null && + previousN > 0 && + previousN < LOW_SAMPLE_N) + ) { + return "Low sample"; + } + return "Good sample"; +} +function sampleLabel(currentN: number, previousN?: number | null): string { + if (previousN == null || previousN <= 0) { + return `Samples ${formatNumber(currentN)}`; + } + return `Samples ${formatNumber(currentN)}; prev ${formatNumber(previousN)}`; +} + +function planningOpportunity( + siteId: string, + row: PlanningRow, + kind: "planning_over" | "planning_under", + p95DeviationPct: number, + briefHref: ( + type: "dwell" | "planning", + node: SiteNode, + kind?: OpportunityKind, + ) => string, + idContext: string, +): SiteOpportunity { + const plan = row.plan ?? 0; + return { + id: opportunityId(siteId, kind, row, idContext), + kind, + siteId, + productId: row.products[0]?.id ?? "", + stepId: row.id, + node: row, + title: row.label, + products: row.products, + typeLabel: kind === "planning_over" ? "Planning over" : "Planning under", + impactLabel: "P95 vs plan", + impactValue: `${p95DeviationPct > 0 ? "+" : ""}${formatNumber(p95DeviationPct, { maximumFractionDigits: 0 })}%`, + impactTone: kind === "planning_over" ? "danger" : "success", + evidence: `Plan ${formatNumber(plan, { maximumFractionDigits: 0 })}d; median ${formatNumber(row.stats.median, { maximumFractionDigits: 1 })}d; P95 ${formatNumber(row.stats.p95, { maximumFractionDigits: 1 })}d`, + sampleLabel: sampleLabel(row.stats.n), + currentSampleN: row.stats.n, + confidenceLabel: confidenceLabel(row.stats.n, null, true, false), + score: Math.abs(p95DeviationPct), + briefHref: briefHref("planning", row, kind), + }; +} +export function buildSiteOpportunities({ + siteId, + dwellRows, + planningRows, + timeRange, + currency, + briefHref, +}: BuildSiteOpportunitiesInput): SiteOpportunity[] { + // Each kind is collected separately then sorted by its own impact (`score`): + // dwell by periodCost, planning by |P95 deviation|. + // This keeps the Opportunities table order independent of the dwell/planning + // table sort. The whole table (set, values, order, and read state) is also + // independent of the Measure dropdown: every gate/metric below reads a fixed + // statistic and `measure` is no longer part of the opportunity id. + const dwellOpps: SiteOpportunity[] = []; + const planningOpps: SiteOpportunity[] = []; + const idContext = timeRange; + for (const row of dwellRows) { + // Gate on a fixed statistic (median), not the live `measure`: the dwell-cost + // opportunity is driven by carrying cost (kg-days x assumptions), so its + // qualification and displayed value must not change when the Measure + // dropdown is toggled. Below the 5k floor the saving isn't worth surfacing. + const days = row.stats.median; + if ( + days == null || + days < DWELL_DAYS_CUTOFF || + row.periodCost < DWELL_MIN_PERIOD_COST + ) { + continue; + } + dwellOpps.push({ + id: opportunityId(siteId, "dwell_cost", row, idContext), + kind: "dwell_cost", + siteId, + productId: row.products[0]?.id ?? "", + stepId: row.id, + node: row, + title: row.label, + products: row.products, + typeLabel: "Dwell cost", + impactLabel: `Cost (${timeRange})`, + impactValue: formatCost(row.periodCost, currency, { compact: true }), + impactTone: "danger", + evidence: `${formatNumber(days, { maximumFractionDigits: 1 })}d observed; ${formatNumber(row.stats.p95, { maximumFractionDigits: 1 })}d P95`, + sampleLabel: sampleLabel(row.stats.n), + currentSampleN: row.stats.n, + confidenceLabel: confidenceLabel( + row.stats.n, + null, + row.cost?.unit_price != null, + false, + ), + score: row.periodCost, + briefHref: briefHref("dwell", row, "dwell_cost"), + }); + } + for (const row of planningRows) { + const p95 = row.stats.p95; + const plan = row.plan; + if (p95 == null || plan == null || plan <= 0) { + continue; + } + const p95DeviationPct = ((p95 - plan) / plan) * 100; + if (p95DeviationPct >= PLANNING_RATIO_THRESHOLD * 100) { + planningOpps.push( + planningOpportunity( + siteId, + row, + "planning_over", + p95DeviationPct, + briefHref, + idContext, + ), + ); + } else if (p95DeviationPct <= -PLANNING_RATIO_THRESHOLD * 100) { + planningOpps.push( + planningOpportunity( + siteId, + row, + "planning_under", + p95DeviationPct, + briefHref, + idContext, + ), + ); + } + } + const byScoreDesc = (a: SiteOpportunity, b: SiteOpportunity) => + b.score - a.score; + dwellOpps.sort(byScoreDesc); + planningOpps.sort(byScoreDesc); + return [...dwellOpps, ...planningOpps]; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/planning-table.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/planning-table.tsx new file mode 100644 index 00000000000..21f68f57bb2 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/planning-table.tsx @@ -0,0 +1,244 @@ +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { BriefLink, StatusActionButton } from "../../shared/action-buttons"; +import { getCategoryColor } from "../../shared/categories"; +import { formatNumber } from "../../shared/cost"; +import { + MEASURE_LABELS, + selectStat, + useBaseMeasure, +} from "../../shared/measure-context"; +import { TrendIndicator } from "../../shared/trend-indicator"; +import { LowSampleBadge } from "./shared/low-sample-badge"; +import { ProductTags } from "./shared/product-tags"; +import { + LOW_SAMPLE_N, + type PlanningRow, + type SortKey, + type SortDir, +} from "./shared/row-types"; +import { siteNodeKey } from "./shared/site-node-key"; +import { SortHeader } from "./shared/sort-header"; +import * as threshold from "./shared/table-styles"; + +import type { SiteNode } from "../../shared/types"; + +const planNote = css({ textStyle: "xxs", color: "fg.subtle", ml: "4" }); + +function isLowSample(row: PlanningRow): boolean { + return ( + (row.stats.n > 0 && row.stats.n < LOW_SAMPLE_N) || + (row.previousTrendN > 0 && row.previousTrendN < LOW_SAMPLE_N) + ); +} + +const PlanningSampleTooltip = ({ + currentN, + previousN, +}: { + currentN: number; + previousN: number; +}) => { + return ( + + {currentN > 0 && currentN < LOW_SAMPLE_N + ? `Current period has ${currentN} observations` + : ""} + {currentN > 0 && + currentN < LOW_SAMPLE_N && + previousN > 0 && + previousN < LOW_SAMPLE_N + ? "; " + : ""} + {previousN > 0 && previousN < LOW_SAMPLE_N + ? `Previous comparison period has ${previousN} observations` + : ""} + + ); +}; +export const PlanningTable = ({ + rows, + sort, + onSort, + onRowClick, + briefHref, + onStatus, +}: { + rows: PlanningRow[]; + sort: { key: SortKey; dir: SortDir }; + onSort: (s: { key: SortKey; dir: SortDir }) => void; + onRowClick: (node: SiteNode) => void; + briefHref: (node: SiteNode) => string; + onStatus: (node: SiteNode, title: string) => void; +}) => { + const { measure } = useBaseMeasure(); + const measureLabel = MEASURE_LABELS[measure]; + const toggleSort = (key: SortKey) => { + if (sort.key === key) { + onSort({ key, dir: sort.dir === "desc" ? "asc" : "desc" }); + } else { + onSort({ key, dir: "desc" }); + } + }; + return ( +
+ + + + + + + + + + + + + + + {rows.map((row) => { + const isOver = row.deviationPct > 0; + return ( + onRowClick(row)} + onKeyDown={(event) => { + if (event.key === "Enter") { + onRowClick(row); + } + }} + tabIndex={0} + className={threshold.bodyRow} + > + + + + + + + + + + ); + })} + {rows.length === 0 && ( + + + + )} + +
+ + ProductsPlanned + + + + + + + + Brief
+
+ + + {row.label} +
+ {row.plan_note && + row.plan_note !== "No planning parameter set" && ( + {row.plan_note} + )} +
+ + + {formatNumber(row.plan, { maximumFractionDigits: 0 })}d + + {formatNumber(selectStat(row.stats, measure) ?? 0, { + maximumFractionDigits: 1, + })} + d + + {isOver ? "+" : ""} + {formatNumber(row.deviationPct, { maximumFractionDigits: 0 })} + % + + + {isLowSample(row) && ( + + + } + /> + + )} + + {row.pct_exceeding_plan != null + ? `${formatNumber(row.pct_exceeding_plan, { maximumFractionDigits: 0 })}%` + : "–"} + +
+ event.stopPropagation()} + /> + + { + event.stopPropagation(); + onStatus(row, row.label); + }} + /> +
+
+ No planning parameter data in the selected period +
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/helpers.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/helpers.ts new file mode 100644 index 00000000000..b5cd8c2ce98 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/helpers.ts @@ -0,0 +1,258 @@ +import { + CATEGORIES, + DWELL_TYPES, + getCategoryForType, +} from "../../../shared/categories"; +import { formatMonth } from "../../../shared/chart-format"; +import { computeMonthlyCost, formatNumber } from "../../../shared/cost"; +import { type BaseMeasure, selectStat } from "../../../shared/measure-context"; +import { + LOW_SAMPLE_N, + type DwellRow, + type PlanningRow, + type SortKey, + type SortDir, +} from "./row-types"; + +import type { + SiteNode, + StepType, + VendorOtifStats, +} from "../../../shared/types"; + +// ── Category filter param helpers ───────────────────────────────────────── + +export const ALL_CATEGORY_KEYS = CATEGORIES.map((column) => column.key); + +export function parseCategoryParam(value: string | null): Set { + if (!value) { + return new Set(ALL_CATEGORY_KEYS); + } + const keys = value + .split(",") + .map((step) => step.trim()) + .filter((key) => ALL_CATEGORY_KEYS.includes(key)); + if (keys.length === 0) { + return new Set(ALL_CATEGORY_KEYS); + } + return new Set(keys); +} + +export function serializeCategoryParam(selected: Set): string | null { + if (selected.size === ALL_CATEGORY_KEYS.length) { + return null; + } + return ALL_CATEGORY_KEYS.filter((key) => selected.has(key)).join(","); +} + +export function categoryMatcher( + selected: Set, +): (type: StepType) => boolean { + if (selected.size === ALL_CATEGORY_KEYS.length) { + return () => true; + } + return (type: StepType) => { + const cat = getCategoryForType(type); + return cat != null && selected.has(cat.key); + }; +} + +// ── Sample / formatting helpers ──────────────────────────────────────────── + +export function hasEnoughSample(count: number): boolean { + return count >= LOW_SAMPLE_N; +} + +export function colorForOtif(otif: number | null): string { + if (otif == null) { + return "#646464"; + } + if (otif >= 95) { + return "#2b9a66"; + } + if (otif >= 80) { + return "#c27803"; + } + return "#ce2c31"; +} + +export function lowSampleBadges( + currentN: number, + previousN?: number | null, +): Array<{ label: string; title: string }> { + const badges: Array<{ label: string; title: string }> = []; + if (currentN > 0 && currentN < LOW_SAMPLE_N) { + badges.push({ + label: "low sample", + title: `Current period has ${currentN} observations`, + }); + } + if (previousN != null && previousN > 0 && previousN < LOW_SAMPLE_N) { + badges.push({ + label: "low sample prev", + title: `Previous comparison period has ${previousN} observations`, + }); + } + return badges; +} + +export function subtitleForVendor(value: VendorOtifStats): string { + const parts: string[] = [`${value.n_lines} lines`]; + if (value.n_late > 0 && value.mean_days_late_when_late != null) { + parts.push( + `mean delay | late: ${formatNumber(value.mean_days_late_when_late, { maximumFractionDigits: 1 })}d`, + ); + } else if (value.n_late === 0) { + parts.push("0 late"); + } + return parts.join(" · "); +} + +// ── Table sorting ────────────────────────────────────────────────────────── + +export function sortRows( + rows: DwellRow[], + sort: { key: SortKey; dir: SortDir }, + measure: BaseMeasure = "median", +): DwellRow[] { + return [...rows].sort((left, right) => { + let va = 0; + let vb = 0; + if (sort.key === "median") { + va = selectStat(left.stats, measure) ?? 0; + vb = selectStat(right.stats, measure) ?? 0; + } else if (sort.key === "cost") { + va = left.periodCost; + vb = right.periodCost; + } else if (sort.key === "costTrend") { + va = + left.costTrendPct ?? + (sort.dir === "desc" + ? Number.NEGATIVE_INFINITY + : Number.POSITIVE_INFINITY); + vb = + right.costTrendPct ?? + (sort.dir === "desc" + ? Number.NEGATIVE_INFINITY + : Number.POSITIVE_INFINITY); + } else if (sort.key === "material") { + return sort.dir === "desc" + ? right.label.localeCompare(left.label) + : left.label.localeCompare(right.label); + } + return sort.dir === "desc" ? vb - va : va - vb; + }); +} + +export function sortPlanningRows( + rows: PlanningRow[], + sort: { key: SortKey; dir: SortDir }, + measure: BaseMeasure = "median", +): PlanningRow[] { + return [...rows].sort((left, right) => { + let va = 0; + let vb = 0; + if (sort.key === "deviation") { + va = left.deviationPct; + vb = right.deviationPct; + } else if (sort.key === "exceeding") { + va = left.pct_exceeding_plan ?? 0; + vb = right.pct_exceeding_plan ?? 0; + } else if (sort.key === "median") { + va = selectStat(left.stats, measure) ?? 0; + vb = selectStat(right.stats, measure) ?? 0; + } else if (sort.key === "trend") { + va = + left.trendPct ?? + (sort.dir === "desc" + ? Number.NEGATIVE_INFINITY + : Number.POSITIVE_INFINITY); + vb = + right.trendPct ?? + (sort.dir === "desc" + ? Number.NEGATIVE_INFINITY + : Number.POSITIVE_INFINITY); + } else if (sort.key === "material") { + return sort.dir === "desc" + ? right.label.localeCompare(left.label) + : left.label.localeCompare(right.label); + } + return sort.dir === "desc" ? vb - va : va - vb; + }); +} + +export function sortSupplierRows( + rows: VendorOtifStats[], + sort: { key: SortKey; dir: SortDir }, +): VendorOtifStats[] { + return [...rows].sort((left, right) => { + if (sort.key === "vendor") { + return sort.dir === "desc" + ? (right.vendor_name ?? "").localeCompare(left.vendor_name ?? "") + : (left.vendor_name ?? "").localeCompare(right.vendor_name ?? ""); + } + const pick = (value: VendorOtifStats): number => { + switch (sort.key) { + case "lines": + return value.n_lines; + case "onTime": + return value.on_time_pct ?? 0; + case "otif": + return value.otif_pct ?? 0; + case "meanLate": + return value.mean_days_late_all ?? 0; + case "meanLateWhenLate": + return value.mean_days_late_when_late ?? 0; + case "maxLate": + return value.max_days_late; + default: + return 0; + } + }; + const av = pick(left); + const bv = pick(right); + return sort.dir === "desc" ? bv - av : av - bv; + }); +} + +// ── Monthly carry-cost aggregation ───────────────────────────────────────── + +export interface SiteMonthlyCostPoint { + month: string; + monthLabel: string; + totalCost: number; + nBatches: number; +} + +export function aggregateMonthlyCarryCost( + nodes: SiteNode[], + waccRate: number, + storageCost: number, +): SiteMonthlyCostPoint[] { + const byMonth = new Map(); + for (const node of nodes) { + if (!DWELL_TYPES.includes(node.type) || !node.cost || !node.monthly) { + continue; + } + for (const month of node.monthly) { + const cost = + computeMonthlyCost( + month.total_kg_days, + node.cost.unit_price, + waccRate, + storageCost, + ) ?? 0; + const entry = byMonth.get(month.month) ?? { totalCost: 0, nBatches: 0 }; + entry.totalCost += cost; + entry.nBatches += month.n; + byMonth.set(month.month, entry); + } + } + return Array.from(byMonth.entries()) + .sort(([left], [right]) => left.localeCompare(right)) + .map(([month, value]) => ({ + month, + monthLabel: formatMonth(month), + ...value, + })); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/low-sample-badge.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/low-sample-badge.tsx new file mode 100644 index 00000000000..2f49cf3e12e --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/low-sample-badge.tsx @@ -0,0 +1,36 @@ +import { Tooltip } from "@hashintel/ds-components"; +import { css } from "@hashintel/ds-helpers/css"; + +import type { ReactNode } from "react"; + +const badge = css({ + display: "inline-flex", + alignItems: "center", + borderRadius: "sm", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "status.warning.bd.subtle", + bg: "status.warning.bg.subtle", + px: "1.5", + py: "[1px]", + textStyle: "xxs", + fontWeight: "medium", + lineHeight: "none", + color: "status.warning.fg.body", + whiteSpace: "nowrap", +}); + +/** Amber pill flagging a row whose sample size is below the reliable threshold. */ +export const LowSampleBadge = ({ + label, + title, +}: { + label: string; + title: ReactNode; +}) => { + return ( + + {label} + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/product-tags.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/product-tags.tsx new file mode 100644 index 00000000000..5add7a15afc --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/product-tags.tsx @@ -0,0 +1,32 @@ +import { css } from "@hashintel/ds-helpers/css"; + +const wrap = css({ display: "flex", flexWrap: "wrap", gap: "1" }); +// Kept as a tunable token chip rather than ds `Badge`: the ds gray badge is a +// fixed 9px with no `className`, which read as too faint in these dense lists. +// `fg.muted` text on `bg.subtle` keeps it legible at xxs. +const chip = css({ + textStyle: "xxs", + fontWeight: "medium", + px: "1.5", + py: "[1px]", + borderRadius: "sm", + bg: "bg.subtle", + color: "fg.muted", +}); + +/** Wrapping list of product chips (falls back to the upper-cased id for long names). */ +export const ProductTags = ({ + products, +}: { + products: Array<{ id: string; name: string }>; +}) => { + return ( + + {products.map((product) => ( + + {product.name.length > 20 ? product.id.toUpperCase() : product.name} + + ))} + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/row-types.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/row-types.ts new file mode 100644 index 00000000000..d311f2dd6e4 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/row-types.ts @@ -0,0 +1,49 @@ +import type { SiteNode } from "../../../shared/types"; + +export const LOW_SAMPLE_N = 10; + +export type Tab = "dwell" | "planning" | "trends" | "suppliers"; + +export type SortKey = + | "median" + | "cost" + | "material" + | "deviation" + | "exceeding" + | "trend" + | "costTrend" + | "vendor" + | "lines" + | "onTime" + | "otif" + | "meanLate" + | "meanLateWhenLate" + | "maxLate"; + +export type SortDir = "asc" | "desc"; + +export type SupplierMode = "worst" | "best"; + +export type DwellRow = SiteNode & { + periodCost: number; + costTrendPct: number | null; + previousPeriodCost: number | null; + previousCostN: number; + /** Timing (measure) trend, shown stacked under the measure-value cell. */ + trendPct: number | null; + previousValue: number | null; + previousTrendN: number; +}; + +export type PlanningRow = SiteNode & { + deviationPct: number; + trendPct: number | null; + previousValue: number | null; + previousTrendN: number; +}; + +export type TrendRow = SiteNode & { + trendPct: number | null; + previousValue: number | null; + previousTrendN: number; +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/site-node-key.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/site-node-key.ts new file mode 100644 index 00000000000..578e067d344 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/site-node-key.ts @@ -0,0 +1,11 @@ +/** + * Stable identity for a site node / table row: the node id plus its product-id + * set (a node can appear once per product grouping). Used for React keys and + * for matching current rows to their historical counterparts. + */ +export function siteNodeKey(node: { + id: string; + products: { id: string }[]; +}): string { + return `${node.id}-${node.products.map((product) => product.id).join(",")}`; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/sort-header.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/sort-header.tsx new file mode 100644 index 00000000000..85ad27fcba6 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/sort-header.tsx @@ -0,0 +1,63 @@ +import { css } from "@hashintel/ds-helpers/css"; + +import type { SortKey, SortDir } from "./row-types"; + +const headerButton = css({ + display: "inline-flex", + alignItems: "center", + gap: "0.5", + transition: "colors", + cursor: "pointer", + _hover: { color: "fg.heading" }, +}); +const caret = css({ flexShrink: 0 }); + +/** Clickable column header that toggles sort key/direction and shows a caret. */ +export const SortHeader = ({ + label, + sortKey, + current, + onToggle, +}: { + label: string; + sortKey: SortKey; + current: { key: SortKey; dir: SortDir }; + onToggle: (key: SortKey) => void; +}) => { + const active = current.key === sortKey; + return ( + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/table-styles.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/table-styles.ts new file mode 100644 index 00000000000..b52708e58c4 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/shared/table-styles.ts @@ -0,0 +1,130 @@ +import { css } from "@hashintel/ds-helpers/css"; + +/** Shared Panda styles for the site-screen tables (dwell / planning / supplier). */ +// Caps the active detail table to the viewport *after* accounting for the site +// header/content padding and the tab bar above this container (`h:11` = 2.75rem). +// The table then scrolls internally as a plain block (matching the Opportunities +// `tableScroll`) so the sticky `th` border travels with the header. +export const TABLE_MAX_HEIGHT = "calc(100dvh - 9.75rem - 100px)"; +export const tableContainer = css({ + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "lg", + bg: "bgSolid.min", + overflow: "auto", +}); +export const table = css({ w: "full", textStyle: "sm", lineHeight: "normal" }); +export const theadRow = css({ + textAlign: "left", + color: "fg.subtle", + borderBottomWidth: "1px", + borderColor: "[#d9d9d9]", + bg: "[#fafafa]", +}); +// Sticky header cells: opaque bg (so scrolled rows don't bleed through) + z above +// body. `top:0` parks them at the top of this container's own scroll area; the +// bottom border matches the Opportunities header (#d9d9d9) and travels with the +// sticky cell. +export const th = css({ + position: "sticky", + top: "0", + zIndex: "[1]", + bg: "[#fafafa]", + borderBottomWidth: "1px", + borderColor: "[#d9d9d9]", + px: "4", + py: "2.5", + fontWeight: "medium", + whiteSpace: "nowrap", +}); +export const thRight = css({ + position: "sticky", + top: "0", + zIndex: "[1]", + bg: "[#fafafa]", + borderBottomWidth: "1px", + borderColor: "[#d9d9d9]", + px: "4", + py: "2.5", + fontWeight: "medium", + textAlign: "right", + whiteSpace: "nowrap", +}); +export const tbodyDivide = css({ + "& > tr": { borderTopWidth: "1px", borderColor: "[#f0f0f0]" }, + "& > tr:first-child": { borderTopWidth: "0" }, +}); +export const bodyRow = css({ + cursor: "pointer", + transition: "colors", + _hover: { bg: "bg.subtle" }, +}); +export const td = css({ px: "4", py: "2.5" }); +export const tdRight = css({ + px: "4", + py: "2.5", + textAlign: "right", + fontVariantNumeric: "tabular-nums", +}); +export const cellFlex = css({ + display: "flex", + alignItems: "center", + gap: "2", +}); +export const catDot = css({ + w: "2", + h: "2", + borderRadius: "full", + flexShrink: 0, +}); +export const stepLabel = css({ fontWeight: "medium", color: "fg.heading" }); +export const valueStrong = css({ color: "fg.heading" }); +export const valueMuted = css({ color: "fg.subtle" }); +export const valueDim = css({ color: "fg.muted" }); +export const numMedium = css({ fontWeight: "medium" }); +export const valueDanger = css({ + fontWeight: "medium", + color: "status.error.fg.body", +}); +export const trendDanger = css({ + fontWeight: "medium", + color: "status.error.fg.body", +}); +export const trendSuccess = css({ + fontWeight: "medium", + color: "status.success.fg.body", +}); +export const sampleCell = css({ + display: "inline-flex", + alignItems: "center", + justifyContent: "flex-end", + gap: "1.5", +}); +export const badgeWrap = css({ + display: "inline-flex", + alignItems: "center", + verticalAlign: "middle", +}); +// Value with a small trend chip stacked beneath it (dwell measure + cost cells). +export const stackedCell = css({ + display: "inline-flex", + flexDirection: "column", + alignItems: "flex-end", + gap: "0.5", +}); +export const stackedTrend = css({ textStyle: "xs" }); +// Stacked Brief + Status actions in the right-most table cell. +export const briefActionStack = css({ + display: "inline-flex", + flexDirection: "column", + alignItems: "flex-end", + gap: "1.5", +}); +export const emptyCell = css({ + px: "4", + py: "6", + textAlign: "center", + color: "fg.subtle", + fontStyle: "italic", +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/site-monthly-carry-cost-chart.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/site-monthly-carry-cost-chart.tsx new file mode 100644 index 00000000000..fae28bf7e91 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/site-monthly-carry-cost-chart.tsx @@ -0,0 +1,111 @@ +import { + Bar, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, + ComposedChart, +} from "recharts"; + +import { css } from "@hashintel/ds-helpers/css"; + +import { + TOOLTIP_CONTENT_STYLE, + TOOLTIP_ITEM_STYLE, + TOOLTIP_LABEL_STYLE, + TOOLTIP_WRAPPER_STYLE, +} from "../../shared/chart-format"; +import { chartTheme } from "../../shared/chart-theme"; +import { formatCost } from "../../shared/cost"; + +import type { SiteMonthlyCostPoint } from "./shared/helpers"; + +const wrap = css({ + borderRadius: "lg", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bgSolid.min", + p: "4", + display: "flex", + flexDirection: "column", + gap: "3", +}); +const title = css({ + textStyle: "sm", + fontWeight: "medium", + color: "fg.heading", +}); +const subtitle = css({ textStyle: "xs", color: "fg.subtle" }); + +export const SiteMonthlyCarryCostChart = ({ + data, + currency, +}: { + data: SiteMonthlyCostPoint[]; + currency: string | null; +}) => { + if (data.length === 0) { + return null; + } + return ( +
+
+

Monthly Carry Cost

+

+ Deduplicated by shared material/intermediate inventory across products +

+
+ + + 12 ? Math.floor(data.length / 8) : 0} + /> + + + formatCost(value, currency, { compact: true }) + } + /> + + String(label)} + formatter={(value) => [ + formatCost(Number(value), currency), + "Total carry cost", + ]} + /> + + + + +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/supplier-table.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/supplier-table.tsx new file mode 100644 index 00000000000..541f5cd650a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/supplier-table.tsx @@ -0,0 +1,213 @@ +import { useMemo } from "react"; + +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { formatNumber } from "../../shared/cost"; +import { colorForOtif, sortSupplierRows } from "./shared/helpers"; +import { SortHeader } from "./shared/sort-header"; +import * as threshold from "./shared/table-styles"; + +import type { VendorOtifStats } from "../../shared/types"; +import type { SortKey, SortDir } from "./shared/row-types"; + +const outerWrap = css({ display: "flex", flexDirection: "column", gap: "2" }); +const vendorCell = css({ + display: "flex", + alignItems: "center", + gap: "2", + minW: "0", +}); +const vendorInner = css({ minW: "0" }); +const vendorName = css({ + fontWeight: "medium", + color: "fg.heading", + overflow: "hidden", + textOverflow: "ellipsis", + whiteSpace: "nowrap", +}); +const vendorId = css({ + textStyle: "xxs", + color: "fg.subtle", + fontVariantNumeric: "tabular-nums", +}); +const materials = css({ textStyle: "xs", color: "fg.subtle" }); +const linesLate = css({ + ml: "1", + textStyle: "xxs", + color: "status.error.fg.body", +}); + +export const SupplierTable = ({ + rows, + sort, + onSort, + onRowClick, +}: { + rows: VendorOtifStats[]; + sort: { key: SortKey; dir: SortDir }; + onSort: (s: { key: SortKey; dir: SortDir }) => void; + onRowClick: (vendor: VendorOtifStats) => void; +}) => { + const sorted = useMemo(() => sortSupplierRows(rows, sort), [rows, sort]); + const toggleSort = (key: SortKey) => { + if (sort.key === key) { + onSort({ key, dir: sort.dir === "desc" ? "asc" : "desc" }); + } else { + onSort({ key, dir: key === "onTime" || key === "otif" ? "asc" : "desc" }); + } + }; + return ( +
+
+ + + + + + + + + + + + + + + {sorted.map((value) => { + const otifColor = colorForOtif(value.otif_pct); + return ( + onRowClick(value)} + onKeyDown={(event) => { + if (event.key === "Enter") { + onRowClick(value); + } + }} + tabIndex={0} + className={threshold.bodyRow} + > + + + + + + + + + + ); + })} + {sorted.length === 0 && ( + + + + )} + +
+ + Materials + + + + + + + + + + + +
+
+ + +
+
+ {value.vendor_name ?? "—"} +
+ {value.vendor_id && ( +
+ Vendor {value.vendor_id} +
+ )} +
+
+
+ + {value.materials?.length ?? 0} + + + {formatNumber(value.n_lines)} + {value.n_late > 0 && ( + ({value.n_late} late) + )} + + {value.on_time_pct != null + ? `${formatNumber(value.on_time_pct, { maximumFractionDigits: 0 })}%` + : "–"} + + {value.otif_pct != null + ? `${formatNumber(value.otif_pct, { maximumFractionDigits: 0 })}%` + : "–"} + + {value.mean_days_late_all != null + ? `${formatNumber(value.mean_days_late_all, { maximumFractionDigits: 1 })}d` + : "–"} + + {value.mean_days_late_when_late != null + ? `${formatNumber(value.mean_days_late_when_late, { maximumFractionDigits: 1 })}d` + : "–"} + + {value.max_days_late > 0 ? `${value.max_days_late}d` : "–"} +
+ No supplier performance data available +
+
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/tab-button.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/tab-button.tsx new file mode 100644 index 00000000000..3112833a10d --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/tab-button.tsx @@ -0,0 +1,41 @@ +import { css, cx } from "@hashintel/ds-helpers/css"; + +const base = css({ + textStyle: "sm", + fontWeight: "medium", + pb: "2", + borderBottomWidth: "2px", + borderBottomStyle: "solid", + transition: "colors", + cursor: "pointer", +}); +const active = css({ borderColor: "fg.heading", color: "fg.heading" }); +const inactive = css({ + borderColor: "[transparent]", + color: "fg.subtle", + _hover: { color: "fg.muted" }, +}); +const count = css({ ml: "1.5", textStyle: "xs", color: "fg.subtle" }); + +export const TabButton = ({ + active: isActive, + onClick, + label, + count: countValue, +}: { + active: boolean; + onClick: () => void; + label: string; + count: number; +}) => { + return ( + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/trend-table.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/trend-table.tsx new file mode 100644 index 00000000000..36cf349a50c --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/trend-table.tsx @@ -0,0 +1,274 @@ +import { useMemo } from "react"; + +import { Icon } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { StatusActionButton } from "../../shared/action-buttons"; +import { getCategoryColor } from "../../shared/categories"; +import { formatNumber } from "../../shared/cost"; +import { trendToneFor } from "../../shared/trend-tone"; +import { LowSampleBadge } from "./shared/low-sample-badge"; +import { ProductTags } from "./shared/product-tags"; +import { + LOW_SAMPLE_N, + type SortDir, + type SortKey, + type TrendRow, +} from "./shared/row-types"; +import { siteNodeKey } from "./shared/site-node-key"; +import { SortHeader } from "./shared/sort-header"; +import * as threshold from "./shared/table-styles"; + +import type { SiteNode } from "../../shared/types"; + +const prevValue = css({ color: "fg.subtle" }); +const trendWrap = css({ + display: "inline-flex", + alignItems: "center", + justifyContent: "flex-end", + gap: "1", + fontVariantNumeric: "tabular-nums", +}); +const trendUp = css({ color: "status.error.fg.body" }); +const trendDown = css({ color: "status.success.fg.body" }); +const trendFlat = css({ color: "fg.subtle" }); +const sampleTooltip = css({ + display: "flex", + flexDirection: "column", + gap: "0.5", + textAlign: "left", +}); + +function sortTrendRows( + rows: TrendRow[], + sort: { key: SortKey; dir: SortDir }, +): TrendRow[] { + return [...rows].sort((left, right) => { + let va = 0; + let vb = 0; + if (sort.key === "median") { + va = left.stats.median ?? 0; + vb = right.stats.median ?? 0; + } else if (sort.key === "trend") { + va = + left.trendPct ?? + (sort.dir === "desc" + ? Number.NEGATIVE_INFINITY + : Number.POSITIVE_INFINITY); + vb = + right.trendPct ?? + (sort.dir === "desc" + ? Number.NEGATIVE_INFINITY + : Number.POSITIVE_INFINITY); + } else if (sort.key === "material") { + return sort.dir === "desc" + ? right.label.localeCompare(left.label) + : left.label.localeCompare(right.label); + } + return sort.dir === "desc" ? vb - va : va - vb; + }); +} + +const EqualsIcon = () => { + return ( + + ); +}; +const TrendValue = ({ + pctChange, +}: { + pctChange: number | null | undefined; +}) => { + const tone = trendToneFor(pctChange); + if (tone == null) { + return -; + } + const toneClass = + tone === "up" ? trendUp : tone === "down" ? trendDown : trendFlat; + return ( + + {tone === "flat" ? ( + + ) : ( + + )} + + {formatNumber(Math.abs(pctChange ?? 0), { maximumFractionDigits: 0 })}% + + + ); +}; + +function isLowSample(row: TrendRow): boolean { + return ( + (row.stats.n > 0 && row.stats.n < LOW_SAMPLE_N) || + (row.previousTrendN > 0 && row.previousTrendN < LOW_SAMPLE_N) + ); +} + +const TrendSampleTooltip = ({ + currentN, + previousN, +}: { + currentN: number; + previousN: number; +}) => { + return ( + + This period: {formatNumber(currentN)} + Last period: {formatNumber(previousN)} + + ); +}; +export const TrendTable = ({ + rows, + sort, + onSort, + onRowClick, + onStatus, +}: { + rows: TrendRow[]; + sort: { key: SortKey; dir: SortDir }; + onSort: (s: { key: SortKey; dir: SortDir }) => void; + onRowClick: (node: SiteNode) => void; + onStatus: (node: SiteNode, title: string) => void; +}) => { + const sortedRows = useMemo(() => sortTrendRows(rows, sort), [rows, sort]); + const toggleSort = (key: SortKey) => { + if (sort.key === key) { + onSort({ key, dir: sort.dir === "desc" ? "asc" : "desc" }); + } else { + onSort({ key, dir: "desc" }); + } + }; + return ( +
+ + + + + + + + + + + + + + {sortedRows.map((row) => ( + onRowClick(row)} + onKeyDown={(event) => { + if (event.key === "Enter") { + onRowClick(row); + } + }} + tabIndex={0} + className={threshold.bodyRow} + > + + + + + + + + + ))} + {sortedRows.length === 0 && ( + + + + )} + +
+ + Products + + Previous median + + SamplesStatus
+
+ + + {row.label} +
+
+ + + {formatNumber(row.stats.median, { maximumFractionDigits: 1 })}d + + {row.previousValue != null + ? `${formatNumber(row.previousValue, { maximumFractionDigits: 1 })}d` + : "-"} + + + + + {isLowSample(row) && ( + + + } + /> + + )} + {formatNumber(row.stats.n)} + + + { + event.stopPropagation(); + onStatus(row, row.label); + }} + /> +
+ No trend data in the selected period +
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-site-overview-rows.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-site-overview-rows.ts new file mode 100644 index 00000000000..c0c4197b9df --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-site-overview-rows.ts @@ -0,0 +1,318 @@ +import { useEffect, useMemo, useState } from "react"; + +import { DWELL_TYPES } from "../../shared/categories"; +import { useCostParams, useOutlierSetting } from "../../shared/cost"; +import { fetchSupplierPerformance } from "../../shared/data"; +import { selectStat, useBaseMeasure } from "../../shared/measure-context"; +import { applyOutlierSelectionToNode } from "../../shared/outlier-selection"; +import { + computeTimingTrend, + computeCostTrend, +} from "../../shared/period-trends"; +import { useProcurementBasis } from "../../shared/procurement-basis-context"; +import { + windowGraphNodeToRange, + applyProcurementBasisToNode, +} from "../../shared/range-filter"; +import { + totalSiteDwellCost, + topDwellCosts, + countBadPlanningParams, + computeNodePeriodCost, +} from "../../shared/site-aggregation"; +import { recomputeSitePerformance } from "../../shared/supplier-otif"; +import { useTimeRange } from "../../shared/time-range-context"; +import { useSiteNodes } from "../../shared/use-site-nodes"; +import { + categoryMatcher, + hasEnoughSample, + sortRows, + sortPlanningRows, + aggregateMonthlyCarryCost, +} from "./shared/helpers"; +import { siteNodeKey } from "./shared/site-node-key"; + +import type { + Product, + SiteNode, + SiteSupplierPerformance, + VendorOtifStats, +} from "../../shared/types"; +import type { SortKey, SortDir, SupplierMode } from "./shared/row-types"; + +interface SiteOverviewRowsInput { + siteSlug: string; + products: Product[]; + selectedCategories: Set; + excludeLowSamples: boolean; + dwellSort: { key: SortKey; dir: SortDir }; + planSort: { key: SortKey; dir: SortDir }; + supplierMode: SupplierMode; + supplierPerformanceEnabled: boolean; +} + +/** + * All derived collections for the site overview (dwell / planning / supplier + * tables + dashboard cards), windowed to the active `timeRange` and the cost / + * outlier filters. Keeps the page component focused on layout + local UI state. + */ +export function useSiteOverviewRows({ + siteSlug, + products, + selectedCategories, + excludeLowSamples, + dwellSort, + planSort, + supplierMode, + supplierPerformanceEnabled, +}: SiteOverviewRowsInput) { + const { currency, setAnalysisSettings, waccRate, storageCost } = + useCostParams(); + const { excludeOutliers } = useOutlierSetting(); + const { measure } = useBaseMeasure(); + const { basis: procurementBasis } = useProcurementBasis(); + const { timeRange } = useTimeRange(); + const { + siteData, + nodes: dedupedNodes, + loading, + error, + } = useSiteNodes(siteSlug, products); + + const [supplierData, setSupplierData] = + useState(null); + + useEffect(() => { + setAnalysisSettings(siteData?.analysis_settings); + }, [siteData?.analysis_settings, setAnalysisSettings]); + + useEffect(() => { + if (!supplierPerformanceEnabled) { + setSupplierData(null); + return; + } + + let cancelled = false; + fetchSupplierPerformance() + .then((suppliers) => { + if (!cancelled) { + setSupplierData(suppliers); + } + }) + .catch(() => { + if (!cancelled) { + setSupplierData(null); + } + }); + return () => { + cancelled = true; + }; + }, [supplierPerformanceEnabled]); + + // Outlier selection is applied once here (full history, used for trends); + // filteredNodes only windows these, so nodes are never double-processed. + // `dedupedNodes` comes from the shared useSiteNodes hook (one fetch + dedup). + const historicalNodes = useMemo((): SiteNode[] => { + return dedupedNodes.map((count) => ({ + ...applyOutlierSelectionToNode( + applyProcurementBasisToNode(count, procurementBasis), + excludeOutliers, + ), + products: count.products, + })); + }, [dedupedNodes, excludeOutliers, procurementBasis]); + + const filteredNodes = useMemo((): SiteNode[] => { + const matchesCategory = categoryMatcher(selectedCategories); + return historicalNodes + .filter((count) => matchesCategory(count.type)) + .map((count) => ({ + ...windowGraphNodeToRange(count, timeRange), + products: count.products, + })); + }, [historicalNodes, timeRange, selectedCategories]); + + const historicalNodesByKey = useMemo(() => { + return new Map(historicalNodes.map((count) => [siteNodeKey(count), count])); + }, [historicalNodes]); + + const planningVisibleNodes = useMemo(() => { + if (!excludeLowSamples) { + return filteredNodes; + } + return filteredNodes.filter((count) => hasEnoughSample(count.stats.n)); + }, [filteredNodes, excludeLowSamples]); + + const summaryStats = useMemo(() => { + const dwellCost = totalSiteDwellCost(filteredNodes, waccRate, storageCost); + const badParams = countBadPlanningParams(filteredNodes, measure); + return { dwellCost: dwellCost > 0 ? dwellCost : null, badParams }; + }, [filteredNodes, waccRate, storageCost, measure]); + + // Site-wide currency for cost formatting: the most common non-null currency + // across the site's nodes. Falls back to the active dataset/default currency. + const siteCurrency = useMemo((): string | null => { + const counts = new Map(); + for (const count of historicalNodes) { + const column = count.cost?.currency; + if (column) { + counts.set(column, (counts.get(column) ?? 0) + 1); + } + } + let best: string | null = null; + let bestN = 0; + for (const [column, count] of counts) { + if (count > bestN) { + best = column; + bestN = count; + } + } + return best ?? currency; + }, [historicalNodes, currency]); + + const topCosts = useMemo( + () => topDwellCosts(filteredNodes, waccRate, storageCost, 5), + [filteredNodes, waccRate, storageCost], + ); + + const monthlyCarryCost = useMemo( + () => aggregateMonthlyCarryCost(filteredNodes, waccRate, storageCost), + [filteredNodes, waccRate, storageCost], + ); + + const dwellRows = useMemo(() => { + const rows = filteredNodes + .filter((count) => DWELL_TYPES.includes(count.type) && count.stats.n > 0) + .map((count) => { + const historical = + historicalNodesByKey.get(siteNodeKey(count)) ?? count; + const costTrend = computeCostTrend( + historical, + timeRange, + waccRate, + storageCost, + ); + const timingTrend = computeTimingTrend(historical, timeRange, measure); + return { + ...count, + periodCost: computeNodePeriodCost(count, waccRate, storageCost), + costTrendPct: costTrend.pctChange, + previousPeriodCost: costTrend.previousTotal, + previousCostN: costTrend.previousN, + trendPct: timingTrend.pctChange, + previousValue: timingTrend.previousValue, + previousTrendN: timingTrend.previousN, + }; + }); + return sortRows(rows, dwellSort, measure); + }, [ + filteredNodes, + historicalNodesByKey, + dwellSort, + waccRate, + storageCost, + timeRange, + measure, + ]); + + const planningRows = useMemo(() => { + const rows = planningVisibleNodes + .filter( + (count) => count.plan != null && count.plan > 0 && count.stats.n > 0, + ) + .map((count) => { + const plan = count.plan as number; + const historical = + historicalNodesByKey.get(siteNodeKey(count)) ?? count; + const trend = computeTimingTrend(historical, timeRange, measure); + return { + ...count, + deviationPct: + (((selectStat(count.stats, measure) ?? 0) - plan) / plan) * 100, + trendPct: trend.pctChange, + previousValue: trend.previousValue, + previousTrendN: trend.previousN, + }; + }); + return sortPlanningRows(rows, planSort, measure); + }, [ + planningVisibleNodes, + historicalNodesByKey, + planSort, + timeRange, + measure, + ]); + + const windowedSupplier = useMemo(() => { + if (!supplierData) { + return null; + } + return recomputeSitePerformance(supplierData, timeRange); + }, [supplierData, timeRange]); + + const supplierRows = useMemo(() => { + if (!windowedSupplier) { + return [] as VendorOtifStats[]; + } + const min = windowedSupplier.overall.min_lines_for_leaderboard; + return windowedSupplier.vendors.filter((value) => value.n_lines >= min); + }, [windowedSupplier]); + + const supplierTop = useMemo(() => { + if (supplierRows.length === 0) { + return [] as VendorOtifStats[]; + } + const sorted = [...supplierRows].sort((left, right) => { + const av = left.otif_pct ?? 0; + const bv = right.otif_pct ?? 0; + if (av === bv) { + return right.n_lines - left.n_lines; + } + return supplierMode === "worst" ? av - bv : bv - av; + }); + return sorted.slice(0, 5); + }, [supplierRows, supplierMode]); + + const trendRows = useMemo(() => { + // Trend opportunities are decoupled from the Measure dropdown: always use the + // fixed median so the Opportunities table doesn't reshuffle when Measure changes. + return planningVisibleNodes + .filter((count) => count.stats.n > 0) + .map((count) => { + const historical = + historicalNodesByKey.get(siteNodeKey(count)) ?? count; + const trend = computeTimingTrend(historical, timeRange, "median"); + return { + ...count, + trendPct: trend.pctChange, + previousValue: trend.previousValue, + previousTrendN: trend.previousN, + }; + }) + .filter( + (count) => !excludeLowSamples || hasEnoughSample(count.previousTrendN), + ); + }, [ + planningVisibleNodes, + historicalNodesByKey, + timeRange, + excludeLowSamples, + ]); + + return { + loading, + error, + filteredNodes, + summaryStats, + siteCurrency, + topCosts, + monthlyCarryCost, + dwellRows, + planningRows, + supplierRows, + supplierTop, + trendRows, + windowedSupplier, + supplierData, + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-supply-chain-status-state.ts b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-supply-chain-status-state.ts new file mode 100644 index 00000000000..80f236850c9 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/use-supply-chain-status-state.ts @@ -0,0 +1,481 @@ +import { useLazyQuery, useMutation } from "@apollo/client"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + +import { + deserializeQueryEntitiesResponse, + HashEntity, +} from "@local/hash-graph-sdk/entity"; +import { + currentTimeInstantTemporalAxes, + generateVersionedUrlMatchingFilter, +} from "@local/hash-isomorphic-utils/graph-queries"; +import { blockProtocolPropertyTypes } from "@local/hash-isomorphic-utils/ontology-type-ids"; + +import { + createEntityMutation, + queryEntitiesQuery, + updateEntityMutation, +} from "../../../../graphql/queries/knowledge/entity.queries"; +import { useAuthInfo } from "../../../shared/auth-info-context"; +import { useScope } from "../../shared/scope-context"; +import { + datetimeDataTypeId, + objectDataTypeId, + supplyChainPropertyBaseUrls, + supplyChainStatusReportEntityTypeId, + supplyChainUserPreferencesEntityTypeId, + textDataTypeId, +} from "../../shared/status-graph-types"; +import { + trackSupplyChainError, + trackSupplyChainInteraction, + trackSupplyChainStatusReportCreated, +} from "../../shared/telemetry"; +import { normalizeStatusOption } from "./opportunities"; + +import type { + CreateEntityMutation, + CreateEntityMutationVariables, + QueryEntitiesQuery, + QueryEntitiesQueryVariables, + UpdateEntityMutation, + UpdateEntityMutationVariables, +} from "../../../../graphql/api-types.gen"; +import type { + OpportunityStatusActions, + OpportunityStatuses, + StatusOption, + StatusStore, +} from "./opportunities"; +import type { + BaseUrl, + Entity, + EntityId, + WebId, +} from "@blockprotocol/type-system"; + +type ReadMarker = { + key: string; + readAt: string; +}; + +const textProperty = (value: string) => ({ + value, + metadata: { dataTypeId: textDataTypeId }, +}); + +const datetimeProperty = (value: string) => ({ + value, + metadata: { dataTypeId: datetimeDataTypeId }, +}); + +const objectArrayProperty = (value: ReadMarker[]) => ({ + value, + metadata: { dataTypeId: objectDataTypeId }, +}); + +const getPropertyValue = ( + entity: Entity, + propertyBaseUrl: BaseUrl, +): T | undefined => { + const raw = entity.properties[propertyBaseUrl] as unknown; + if (raw && typeof raw === "object" && "value" in raw) { + return (raw as { value: T }).value; + } + return raw as T | undefined; +}; + +const statusReportQuery = ({ + siteId, + webId, +}: { + siteId: string; + webId: WebId; +}) => ({ + filter: { + all: [ + { equal: [{ path: ["webId"] }, { parameter: webId }] }, + generateVersionedUrlMatchingFilter(supplyChainStatusReportEntityTypeId, { + ignoreParents: false, + }), + { + equal: [ + { path: ["properties", supplyChainPropertyBaseUrls.siteId] }, + { parameter: siteId }, + ], + }, + ], + }, + temporalAxes: currentTimeInstantTemporalAxes, + includeDrafts: false, + includePermissions: false, +}); + +const preferencesQuery = ({ + userId, + webId, +}: { + userId: string; + webId: WebId; +}) => ({ + filter: { + all: [ + { equal: [{ path: ["webId"] }, { parameter: webId }] }, + generateVersionedUrlMatchingFilter( + supplyChainUserPreferencesEntityTypeId, + { + ignoreParents: false, + }, + ), + { + equal: [ + { + path: ["properties", supplyChainPropertyBaseUrls.preferencesUserId], + }, + { parameter: userId }, + ], + }, + { + equal: [ + { + path: ["properties", supplyChainPropertyBaseUrls.preferencesWebId], + }, + { parameter: webId }, + ], + }, + ], + }, + temporalAxes: currentTimeInstantTemporalAxes, + includeDrafts: false, + includePermissions: false, +}); + +const buildStatuses = (readMarkers: ReadMarker[]): OpportunityStatuses => + Object.fromEntries( + readMarkers.map((marker) => [ + marker.key, + { read: true, readAt: marker.readAt }, + ]), + ); + +const parseStatusReports = (entities: Entity[]): StatusStore => { + const store: StatusStore = {}; + + for (const entity of entities) { + const key = getPropertyValue( + entity, + supplyChainPropertyBaseUrls.scopeKey, + ); + if (!key) { + continue; + } + + const entry = { + at: + getPropertyValue( + entity, + supplyChainPropertyBaseUrls.statusReportCreatedAt, + ) ?? new Date().toISOString(), + category: normalizeStatusOption( + getPropertyValue( + entity, + supplyChainPropertyBaseUrls.statusCategory, + ), + ), + text: + getPropertyValue( + entity, + supplyChainPropertyBaseUrls.statusText, + ) ?? "", + user: + getPropertyValue( + entity, + supplyChainPropertyBaseUrls.statusReportAuthorId, + ) ?? "Unknown user", + }; + + store[key] = [...(store[key] ?? []), entry]; + } + + for (const entries of Object.values(store)) { + entries.sort((left, right) => left.at.localeCompare(right.at)); + } + + return store; +}; + +const parseStatusKey = (key: string) => { + const [siteId = "", opportunityType = "", nodeKey = ""] = key.split("::"); + const [stepId = "", productIds = ""] = nodeKey.split("-"); + const [productId = ""] = productIds.split(","); + return { opportunityType, productId, siteId, stepId }; +}; + +export const useSupplyChainStatusState = ( + siteId: string, +): { + actions: OpportunityStatusActions; + statusHistory: StatusStore; + statuses: OpportunityStatuses; +} => { + const scope = useScope() as WebId; + const { authenticatedUser } = useAuthInfo(); + const userId = authenticatedUser?.accountId; + const userLabel = + authenticatedUser?.displayName ?? authenticatedUser?.shortname ?? userId; + + const [statusHistory, setStatusHistory] = useState({}); + const [readMarkers, setReadMarkers] = useState([]); + const [preferencesEntityId, setPreferencesEntityId] = + useState(null); + const writeQueueRef = useRef(Promise.resolve()); + + const [queryEntities] = useLazyQuery< + QueryEntitiesQuery, + QueryEntitiesQueryVariables + >(queryEntitiesQuery, { fetchPolicy: "network-only" }); + const [createEntity] = useMutation< + CreateEntityMutation, + CreateEntityMutationVariables + >(createEntityMutation); + const [updateEntity] = useMutation< + UpdateEntityMutation, + UpdateEntityMutationVariables + >(updateEntityMutation); + + const loadStatusReports = useCallback(async () => { + if (!siteId) { + setStatusHistory({}); + return; + } + + const { data } = await queryEntities({ + variables: { request: statusReportQuery({ siteId, webId: scope }) }, + }); + + setStatusHistory( + data?.queryEntities + ? parseStatusReports( + deserializeQueryEntitiesResponse(data.queryEntities).entities, + ) + : {}, + ); + }, [queryEntities, scope, siteId]); + + const loadPreferences = useCallback(async () => { + if (!userId) { + setPreferencesEntityId(null); + setReadMarkers([]); + return; + } + + const { data } = await queryEntities({ + variables: { + request: preferencesQuery({ userId, webId: scope }), + }, + }); + + const preferencesEntity = data?.queryEntities + ? deserializeQueryEntitiesResponse(data.queryEntities).entities[0] + : undefined; + + setPreferencesEntityId( + preferencesEntity?.metadata.recordId.entityId ?? null, + ); + setReadMarkers( + preferencesEntity + ? (getPropertyValue( + preferencesEntity, + supplyChainPropertyBaseUrls.readMarkers, + ) ?? []) + : [], + ); + }, [queryEntities, scope, userId]); + + useEffect(() => { + void loadStatusReports(); + }, [loadStatusReports]); + + useEffect(() => { + void loadPreferences(); + }, [loadPreferences]); + + const ensurePreferencesEntity = useCallback(async (): Promise => { + if (preferencesEntityId) { + return preferencesEntityId; + } + if (!userId) { + throw new Error("Cannot save supply-chain preferences without a user."); + } + + const { data } = await createEntity({ + variables: { + entityTypeIds: [supplyChainUserPreferencesEntityTypeId], + webId: scope, + properties: { + [blockProtocolPropertyTypes.name.propertyTypeBaseUrl]: textProperty( + `Supply-chain preferences for ${userId}`, + ), + [supplyChainPropertyBaseUrls.preferencesUserId]: textProperty(userId), + [supplyChainPropertyBaseUrls.preferencesWebId]: textProperty(scope), + [supplyChainPropertyBaseUrls.readMarkers]: objectArrayProperty([]), + } as unknown as CreateEntityMutationVariables["properties"], + }, + }); + + const entityId = data?.createEntity + ? new HashEntity(data.createEntity).metadata.recordId.entityId + : undefined; + if (!entityId) { + throw new Error("Failed to create supply-chain preferences."); + } + setPreferencesEntityId(entityId); + return entityId; + }, [createEntity, preferencesEntityId, scope, userId]); + + const persistReadMarkers = useCallback( + (nextMarkers: ReadMarker[]) => { + writeQueueRef.current = writeQueueRef.current + .catch(() => undefined) + .then(async () => { + const entityId = await ensurePreferencesEntity(); + await updateEntity({ + variables: { + entityUpdate: { + entityId, + propertyPatches: [ + { + op: "add", + path: [supplyChainPropertyBaseUrls.readMarkers], + property: objectArrayProperty(nextMarkers), + }, + ], + }, + }, + }); + }); + }, + [ensurePreferencesEntity, updateEntity], + ); + + const onMarkRead = useCallback( + (key: string) => { + const readAt = new Date().toISOString(); + trackSupplyChainInteraction({ + interaction: "opportunity_marked_read", + siteId, + source: "opportunities_table", + }); + setReadMarkers((currentMarkers) => { + const nextMarkers = [ + ...currentMarkers.filter((marker) => marker.key !== key), + { key, readAt }, + ]; + persistReadMarkers(nextMarkers); + return nextMarkers; + }); + }, + [persistReadMarkers, siteId], + ); + + const onMarkUnread = useCallback( + (key: string) => { + trackSupplyChainInteraction({ + interaction: "opportunity_marked_unread", + siteId, + source: "opportunities_table", + }); + setReadMarkers((currentMarkers) => { + const nextMarkers = currentMarkers.filter( + (marker) => marker.key !== key, + ); + persistReadMarkers(nextMarkers); + return nextMarkers; + }); + }, + [persistReadMarkers, siteId], + ); + + const onSaveStatus = useCallback( + (key: string, status: { category: StatusOption; text: string }) => { + if (!userId) { + return; + } + + const createdAt = new Date().toISOString(); + const parsedKey = parseStatusKey(key); + trackSupplyChainStatusReportCreated({ + opportunityType: parsedKey.opportunityType, + productId: parsedKey.productId, + siteId: parsedKey.siteId || siteId, + source: "status_dialog", + stepId: parsedKey.stepId, + }); + const entry = { + at: createdAt, + category: status.category, + text: status.text, + user: userLabel ?? userId, + }; + + setStatusHistory((currentHistory) => ({ + ...currentHistory, + [key]: [...(currentHistory[key] ?? []), entry], + })); + + void createEntity({ + variables: { + entityTypeIds: [supplyChainStatusReportEntityTypeId], + webId: scope, + properties: { + [supplyChainPropertyBaseUrls.scopeKey]: textProperty(key), + [supplyChainPropertyBaseUrls.productId]: textProperty( + parsedKey.productId, + ), + [supplyChainPropertyBaseUrls.siteId]: textProperty( + parsedKey.siteId || siteId, + ), + [supplyChainPropertyBaseUrls.stepId]: textProperty( + parsedKey.stepId, + ), + [supplyChainPropertyBaseUrls.opportunityType]: textProperty( + parsedKey.opportunityType, + ), + [supplyChainPropertyBaseUrls.statusCategory]: textProperty( + status.category, + ), + [supplyChainPropertyBaseUrls.statusText]: textProperty(status.text), + [supplyChainPropertyBaseUrls.statusReportAuthorId]: textProperty( + userLabel ?? userId, + ), + [supplyChainPropertyBaseUrls.statusReportCreatedAt]: + datetimeProperty(createdAt), + } as unknown as CreateEntityMutationVariables["properties"], + }, + }).catch(() => { + trackSupplyChainError({ + interaction: "status_report_create_failed", + opportunityType: parsedKey.opportunityType, + productId: parsedKey.productId, + siteId: parsedKey.siteId || siteId, + source: "status_dialog", + stepId: parsedKey.stepId, + }); + void loadStatusReports(); + }); + }, + [createEntity, loadStatusReports, scope, siteId, userId, userLabel], + ); + + const statuses = useMemo(() => buildStatuses(readMarkers), [readMarkers]); + + return { + actions: { + onMarkRead, + onMarkUnread, + onSaveStatus, + }, + statusHistory, + statuses, + }; +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/app-shell/site/vendor-detail-panel.tsx b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/vendor-detail-panel.tsx new file mode 100644 index 00000000000..b8795cc6511 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/app-shell/site/vendor-detail-panel.tsx @@ -0,0 +1,367 @@ +import { useEffect, useState, useMemo } from "react"; +import { + LineChart, + Line, + XAxis, + YAxis, + Tooltip as RTooltip, + ResponsiveContainer, +} from "recharts"; + +import { Button } from "@hashintel/ds-components"; +import { css } from "@hashintel/ds-helpers/css"; + +import { chartTheme } from "../../shared/chart-theme"; +import { formatNumber } from "../../shared/cost"; +import { fetchSupplierPerformance } from "../../shared/data"; +import { LoadingState } from "../../shared/load-state"; +import { SlideOver, SlideOverClose } from "../../shared/slide-over"; +import { recomputeSitePerformance } from "../../shared/supplier-otif"; +import { VendorCard, WorstEventsTable } from "../../shared/vendor-cards"; + +import type { TimeRange } from "../../shared/time-range"; +import type { + SiteSupplierPerformance, + VendorOtifStats, +} from "../../shared/types"; + +const header = css({ + borderBottomWidth: "1px", + borderColor: "bd.subtle", + p: "6", +}); +const headerRow = css({ + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", +}); +const headerMain = css({ flex: "1", minW: "0" }); +// Bottom spacing only — the back control itself is now a ds `Button` (linkSubtle). +const backLink = css({ mb: "2" }); +const title = css({ + fontFamily: "display", + textStyle: "2xl", + fontWeight: "medium", + color: "fg.heading", + lineHeight: "[30px]", +}); +const subId = css({ + textStyle: "sm", + color: "fg.subtle", + mt: "1", + fontVariantNumeric: "tabular-nums", +}); +const subWindow = css({ ml: "2", color: "fg.subtle" }); +const loadingH = css({ h: "32" }); +const emptyMsg = css({ p: "6", textStyle: "sm", color: "fg.subtle" }); +const section = css({ + borderTopWidth: "1px", + borderColor: "bd.subtle", + p: "6", + display: "flex", + flexDirection: "column", + gap: "3", +}); +const sectionTitle = css({ + textStyle: "base", + fontWeight: "medium", + color: "fg.heading", +}); + +const mbtContainer = css({ + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "md", + overflow: "hidden", +}); +const mbtTable = css({ w: "full", textStyle: "sm", lineHeight: "normal" }); +const mbtHeadRow = css({ + textAlign: "left", + color: "fg.subtle", + bg: "bg.subtle", + borderBottomWidth: "1px", + borderColor: "bd.subtle", +}); +const mbtTh = css({ px: "3", py: "2", fontWeight: "medium" }); +const mbtThRight = css({ + px: "3", + py: "2", + fontWeight: "medium", + textAlign: "right", +}); +const mbtBody = css({ + "& > tr": { borderTopWidth: "1px", borderColor: "[#f0f0f0]" }, + "& > tr:first-child": { borderTopWidth: "0" }, +}); +const mbtRow = css({ _hover: { bg: "bg.subtle" } }); +const mbtTdName = css({ px: "3", py: "2", color: "fg.heading" }); +const mbtTdNum = css({ + px: "3", + py: "2", + textAlign: "right", + fontVariantNumeric: "tabular-nums", + color: "fg.muted", +}); +const mbtTdStrong = css({ + px: "3", + py: "2", + textAlign: "right", + fontVariantNumeric: "tabular-nums", + fontWeight: "medium", + color: "fg.heading", +}); +const chartWrap = css({ h: "48" }); + +interface VendorDetailPanelProps { + vendorId: string; + onClose: () => void; + dateRange?: TimeRange; + windowLabel?: string; +} + +const MaterialBreakdownTable = ({ + materials, +}: { + materials: NonNullable; +}) => { + return ( +
+ + + + + + + + + + + {materials.map((month) => ( + + + + + + + ))} + +
MaterialLinesOn-time %OTIF %
{month.name}{formatNumber(month.n_lines)} + {month.on_time_pct != null + ? `${formatNumber(month.on_time_pct, { maximumFractionDigits: 0 })}%` + : "—"} + + {month.otif_pct != null + ? `${formatNumber(month.otif_pct, { maximumFractionDigits: 0 })}%` + : "—"} +
+
+ ); +}; + +const MonthlyTrendChart = ({ + monthly, +}: { + monthly: NonNullable; +}) => { + const points = monthly.map((month) => ({ + month: month.month, + on_time_pct: month.on_time_pct, + n: month.n, + })); + return ( +
+ + + + + `${value}%`} + tickLine={false} + axisLine={false} + width={36} + /> + + { + const value2 = typeof value === "number" ? value : Number(value); + const count = + (item as { payload?: { n?: number } } | undefined)?.payload + ?.n ?? 0; + return [ + `${formatNumber(value2, { maximumFractionDigits: 0 })}% (n=${count})`, + "On-time", + ]; + }} + /> + + + + +
+ ); +}; +export const VendorDetailPanel = ({ + vendorId, + onClose, + dateRange, + windowLabel, +}: VendorDetailPanelProps) => { + const [data, setData] = useState(null); + const [loading, setLoading] = useState(true); + useEffect(() => { + setLoading(true); + void fetchSupplierPerformance() + .then(setData) + .finally(() => setLoading(false)); + }, []); + const windowed = useMemo(() => { + if (!data) { + return null; + } + return recomputeSitePerformance(data, dateRange); + }, [data, dateRange]); + const vendor = useMemo(() => { + if (!windowed) { + return null; + } + return ( + windowed.vendors.find((value) => value.vendor_id === vendorId) ?? null + ); + }, [windowed, vendorId]); // Fallback to the unfiltered vendor record so we can show the name even + // when the windowed view has zero lines for this vendor. + const fallbackVendor = useMemo(() => { + if (!data) { + return null; + } + return data.vendors.find((value) => value.vendor_id === vendorId) ?? null; + }, [data, vendorId]); + const headerVendor = vendor ?? fallbackVendor; + const hasWindowedData = vendor !== null && vendor.n_lines > 0; + return ( + + {/* Header */} +
+
+
+ + {(close) => ( + + )} + +

+ {headerVendor?.vendor_name ?? "Loading vendor..."} +

+ {headerVendor?.vendor_id && ( +

+ Vendor {headerVendor.vendor_id} + {windowLabel && ( + + · {windowLabel.toLowerCase()} + + )} +

+ )} +
+ + {(close) => ( +
+
+ + {/* Body */} +
+ {loading && ( + + )} + {!loading && !headerVendor && ( +
+ Vendor not found in the supplier performance dataset. +
+ )} + {!loading && headerVendor && !hasWindowedData && ( +
+ {windowLabel + ? `No measurable lines for this vendor in the selected window (${windowLabel.toLowerCase()}).` + : "No measurable lines for this vendor."} +
+ )} + {!loading && vendor && hasWindowedData && ( + <> + {/* Vendor card (reused from SupplierDimensionView) */} + + + {/* Material breakdown */} + {vendor.materials && vendor.materials.length > 0 && ( +
+

Materials supplied

+ +
+ )} + + {/* Monthly on-time % */} + {vendor.monthly && vendor.monthly.length > 0 && ( +
+

Monthly on-time %

+ +
+ )} + + {/* Worst events */} + {vendor.worst_events && vendor.worst_events.length > 0 && ( +
+

Worst late events

+ +
+ )} + + )} +
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain.page/product/[product-id].page.tsx b/apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx similarity index 75% rename from apps/hash-frontend/src/pages/supply-chain.page/product/[product-id].page.tsx rename to apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx index 08b9d591fd3..64fa6f4e5ad 100644 --- a/apps/hash-frontend/src/pages/supply-chain.page/product/[product-id].page.tsx +++ b/apps/hash-frontend/src/pages/supply-chain/product/[product-id].page.tsx @@ -3,17 +3,18 @@ import { useCallback, useEffect, useState } from "react"; import { css } from "@hashintel/ds-helpers/css"; -import { Overview } from "../../../vct/supply-chain/product"; -import { fetchGraph } from "../../../vct/supply-chain/shared/data"; -import { - ErrorState, - LoadingState, -} from "../../../vct/supply-chain/shared/load-state"; -import { useSearchParams } from "../../../vct/supply-chain/shared/use-search-params"; +import { Overview } from "../app-shell/product"; +import { fetchGraph } from "../shared/data"; +import { ErrorState, LoadingState } from "../shared/load-state"; import { getSupplyChainLayout } from "../shared/supply-chain-layout"; +import { + trackSupplyChainError, + trackSupplyChainViewed, +} from "../shared/telemetry"; +import { useSearchParams } from "../shared/use-search-params"; import type { NextPageWithLayout } from "../../../shared/layout"; -import type { GraphData } from "../../../vct/supply-chain/shared/types"; +import type { GraphData } from "../shared/types"; const loadingH = css({ h: "64" }); const errorPad = css({ px: "6", py: "4" }); @@ -56,11 +57,21 @@ const ProductPage: NextPageWithLayout = () => { } setLoading(true); setError(null); + trackSupplyChainViewed({ + productId, + route: "/supply-chain/product/[product-id]", + source: "product_page", + }); fetchGraph(productId) .then(setGraph) - .catch((caught) => - setError(caught instanceof Error ? caught.message : String(caught)), - ) + .catch((caught) => { + trackSupplyChainError({ + interaction: "product_graph_fetch_failed", + productId, + source: "product_page", + }); + setError(caught instanceof Error ? caught.message : String(caught)); + }) .finally(() => setLoading(false)); }, [productId]); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/action-button-styles.ts b/apps/hash-frontend/src/pages/supply-chain/shared/action-button-styles.ts new file mode 100644 index 00000000000..c9fd7e73c78 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/action-button-styles.ts @@ -0,0 +1,40 @@ +import { css } from "@hashintel/ds-helpers/css"; + +export const briefLinkStyle = css({ + display: "inline-flex", + alignItems: "center", + gap: "1.5", + borderRadius: "sm", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "[#bfdbfe]", + bg: "[#eff6ff]", + px: "2.5", + py: "1", + textStyle: "xs", + lineHeight: "none", + fontWeight: "medium", + color: "[#1d4ed8]", + whiteSpace: "nowrap", + _hover: { borderColor: "[#93c5fd]", bg: "[#dbeafe]", color: "[#1e40af]" }, +}); + +export const neutralActionButtonStyle = css({ + display: "inline-flex", + alignItems: "center", + gap: "1.5", + borderRadius: "sm", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bgSolid.min", + px: "2.5", + py: "1", + textStyle: "xs", + lineHeight: "none", + fontWeight: "medium", + color: "fg.muted", + cursor: "pointer", + whiteSpace: "nowrap", + _hover: { borderColor: "bd.strong", color: "fg.heading" }, +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/action-buttons.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/action-buttons.tsx new file mode 100644 index 00000000000..06d5b20f456 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/action-buttons.tsx @@ -0,0 +1,124 @@ +import { Icon } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { Link } from "../../../shared/ui/link"; +import { + briefLinkStyle, + neutralActionButtonStyle, +} from "./action-button-styles"; +import { StatusIcon } from "./status-dialog"; + +import type { MouseEventHandler, ReactNode } from "react"; + +// ── Square "?" docs button (identical in the main header + slide-over) ────── +const docsButton = css({ + display: "inline-flex", + alignItems: "center", + justifyContent: "center", + h: "7", + w: "7", + borderRadius: "md", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bgSolid.min", + color: "fg.subtle", + cursor: "pointer", + transition: "colors", + _hover: { color: "fg.heading", bg: "bg.subtle" }, +}); +const docsButtonActive = css({ color: "fg.heading", bg: "bg.subtle" }); + +export const DocsIconButton = ({ + onClick, + label = "Open documentation", + active = false, + className, +}: { + onClick: () => void; + label?: string; + active?: boolean; + className?: string; +}) => { + return ( + + ); +}; + +// ── Shared Brief / Status / Data pill buttons ─────────────────────────────── +// One source of truth for the action buttons that appear in the opportunities +// table, the dwell/planning tables, and the slide-over header. + +/** Blue "Brief" link that opens the opportunity brief in a new tab. */ +export const BriefLink = ({ + href, + onClick, + className, +}: { + href: string; + onClick?: MouseEventHandler; + className?: string; +}) => { + return ( + + + Brief + + ); +}; + +/** White pill button used for the Status / Data actions. */ +export const NeutralActionButton = ({ + onClick, + icon, + children, + className, +}: { + onClick: MouseEventHandler; + icon?: ReactNode; + children: ReactNode; + className?: string; +}) => { + return ( + + ); +}; + +/** Convenience: the standard white "Status" button. */ +export const StatusActionButton = ({ + onClick, + className, +}: { + onClick: MouseEventHandler; + className?: string; +}) => { + return ( + } + className={className} + > + Status + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/carrying-cost.characterization.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/carrying-cost.characterization.test.ts new file mode 100644 index 00000000000..40aa80251be --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/carrying-cost.characterization.test.ts @@ -0,0 +1,88 @@ +import { describe, expect, it } from "vitest"; + +import { computeMonthlyCost, costRatePerKgDay } from "./cost"; +import { computeNodePeriodCost } from "./site-aggregation"; + +import type { CostData, MonthlyBucket, SiteNode, StepStats } from "./types"; + +// Characterization tests pinning the CURRENT carrying-cost period-summation +// behaviour before the ~10 duplicated reduce copies are collapsed into a single +// lib/cost.computePeriodCost helper (Batch 3). The new helper MUST reproduce +// this golden total exactly. + +const zeroStats: StepStats = { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, +}; + +function cost(unitPrice: number | null): CostData { + return { unit_price: unitPrice, currency: "EUR" }; +} + +function kgDayMonth(month: string, totalKgDays: number): MonthlyBucket { + return { month, mean: null, median: null, n: 1, total_kg_days: totalKgDays }; +} + +function siteNode(overrides: Partial): SiteNode { + return { + id: "n", + label: "Node", + type: "intermediate_dwell", + material: null, + plant: "PL-A", + stats: zeroStats, + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: null, + products: [{ id: "p1", name: "P1" }], + ...overrides, + }; +} + +describe("carrying-cost period summation characterization", () => { + const wacc = 0.1; + const storage = 0.336; + const unitPrice = 100; + const months = [ + kgDayMonth("2025-11", 1000), + kgDayMonth("2025-12", 500), + kgDayMonth("2026-01", 2500), + ]; + + it("sums Sigma(total_kg_days * rate) across monthly buckets", () => { + const rate = costRatePerKgDay(unitPrice, wacc, storage); + const expected = (1000 + 500 + 2500) * rate; + const node = siteNode({ cost: cost(unitPrice), monthly: months }); + expect(computeNodePeriodCost(node, wacc, storage)).toBeCloseTo(expected, 6); + }); + + it("equals the per-bucket computeMonthlyCost sum (invariant the dedup must preserve)", () => { + const node = siteNode({ cost: cost(unitPrice), monthly: months }); + const manual = months.reduce( + (sum, month) => + sum + + (computeMonthlyCost( + month.total_kg_days ?? null, + unitPrice, + wacc, + storage, + ) ?? 0), + 0, + ); + expect(computeNodePeriodCost(node, wacc, storage)).toBeCloseTo(manual, 6); + }); + + it("is zero when the node has no unit price", () => { + const node = siteNode({ cost: cost(null), monthly: months }); + expect(computeNodePeriodCost(node, wacc, storage)).toBe(0); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/categories.ts b/apps/hash-frontend/src/pages/supply-chain/shared/categories.ts new file mode 100644 index 00000000000..a123b13e4ce --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/categories.ts @@ -0,0 +1,101 @@ +import type { StepType } from "./types"; + +export type CategoryIcon = + | "puzzle" + | "clock" + | "blocks" + | "search-check" + | "truck"; + +export interface Category { + key: string; + label: string; + color: string; + icon: CategoryIcon; + types: StepType[]; + hidden?: boolean; +} + +export const CATEGORIES: Category[] = [ + { + key: "dwell", + label: "Dwell", + color: "#989898", + icon: "clock", + types: [ + "raw_material_dwell", + "intermediate_dwell", + "post_qa_ship", + "destination_dwell", + ], + }, + { + key: "procurement", + label: "Procurement", + color: "#64ade6", + icon: "puzzle", + types: ["procurement"], + }, + { + key: "production", + label: "Production", + color: "#9797fe", + icon: "blocks", + types: ["production"], + }, + { + key: "qa", + label: "QA", + color: "#3cc3b3", + icon: "search-check", + types: ["qa_hold"], + }, + { + key: "logistics", + label: "Logistics", + color: "#ff9c5e", + icon: "truck", + types: ["transit"], + }, +]; + +export const PIPELINE_COLORS: Record = { + procurement: "#64ade6", + raw_material_dwell: "#989898", + intermediate_dwell: "#989898", + production: "#9797fe", + qa_hold: "#3cc3b3", + post_qa_ship: "#989898", + transit: "#ff9c5e", + destination_dwell: "#989898", +}; + +export const DWELL_TYPES: StepType[] = [ + "raw_material_dwell", + "intermediate_dwell", + "destination_dwell", + "post_qa_ship", +]; + +export function getCategoryForType(type: StepType): Category | undefined { + return CATEGORIES.find((column) => column.types.includes(type)); +} + +export function getCategoryColor(type: StepType): string { + return PIPELINE_COLORS[type] ?? "#94a3b8"; +} + +export function isDwellType(type: StepType): boolean { + return DWELL_TYPES.includes(type); +} + +export function getCategoryIcon(type: StepType): CategoryIcon { + const cat = getCategoryForType(type); + return cat?.icon ?? "puzzle"; +} + +export const PRODUCTION_TYPES: StepType[] = ["production"]; + +export function isProductionType(type: StepType): boolean { + return PRODUCTION_TYPES.includes(type); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/chart-format.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/chart-format.test.ts new file mode 100644 index 00000000000..ab329854d1a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/chart-format.test.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from "vitest"; + +import { formatMonth } from "./chart-format"; + +describe("formatMonth", () => { + it("formats a YYYY-MM string as 'Mon YY'", () => { + expect(formatMonth("2024-01")).toBe("Jan 24"); + expect(formatMonth("2025-12")).toBe("Dec 25"); + expect(formatMonth("2026-06")).toBe("Jun 26"); + }); + + it("handles single-digit and double-digit months", () => { + expect(formatMonth("2024-03")).toBe("Mar 24"); + expect(formatMonth("2024-11")).toBe("Nov 24"); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/chart-format.ts b/apps/hash-frontend/src/pages/supply-chain/shared/chart-format.ts new file mode 100644 index 00000000000..9fa33d92d56 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/chart-format.ts @@ -0,0 +1,61 @@ +import { token } from "@hashintel/ds-helpers/tokens"; + +import type { CSSProperties } from "react"; + +const MONTH_ABBREVIATIONS = [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", +]; + +// Shared Recharts tooltip styling. Recharts inspects the *element type* of its +// direct children, so the `` element must stay inline in each chart; +// these style objects are spread into it to keep the look identical. Colors come +// from ds-components tokens (`var(--colors-…)`); charts render inside the +// supply-chain `.hash-ds-root` scope so the vars resolve. +// +// Light surface (matches the distribution chart's tooltip) — preferred for +// readability over the previous dark `neutral.s120` pill. +export const TOOLTIP_CONTENT_STYLE: CSSProperties = { + fontSize: 12, + borderRadius: 8, + border: `1px solid ${token.var("colors.bd.subtle")}`, + boxShadow: "0 2px 8px rgba(0,0,0,0.08)", + backgroundColor: token.var("colors.bgSolid.min"), + color: token.var("colors.fg.body"), + fontFamily: "inherit", +}; + +export const TOOLTIP_LABEL_STYLE: CSSProperties = { + color: token.var("colors.fg.body"), + fontSize: 11, +}; +export const TOOLTIP_ITEM_STYLE: CSSProperties = { + color: token.var("colors.fg.body"), +}; +export const TOOLTIP_WRAPPER_STYLE: CSSProperties = { zIndex: 9999 }; + +/** + * Formats a `YYYY-MM` string as a short `Mon YY` axis label (e.g. `Jan 24`). + * Shared by every monthly chart (cost, trend, savings, site carry cost). + */ +export function formatMonth(ym: string): string { + const [year, month] = ym.split("-"); + if (!year || !month) { + return ym; + } + const monthLabel = MONTH_ABBREVIATIONS[Number.parseInt(month, 10) - 1]; + if (!monthLabel) { + return ym; + } + return `${monthLabel} ${year.slice(2)}`; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/chart-kit.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/chart-kit.tsx new file mode 100644 index 00000000000..b7fa048cd52 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/chart-kit.tsx @@ -0,0 +1,183 @@ +import { css } from "@hashintel/ds-helpers/css"; + +import { chartTheme } from "./chart-theme"; + +import type { KeyboardEvent, MouseEvent } from "react"; + +/** + * Shared visual primitives for the Recharts-based charts: the custom tick/dot + * SVG renderers and the legend swatch. The dark tooltip style objects live in + * `chart-format.ts` (a non-component module) because Recharts inspects the + * element type of its direct children and the `` must stay inline. + */ + +const legendRowSm = css({ display: "flex", alignItems: "center", gap: "1" }); +const legendRowMd = css({ display: "flex", alignItems: "center", gap: "1.5" }); +const swatchDashed = css({ + width: "4", + height: "0", + borderTopWidth: "2px", + borderTopStyle: "dashed", +}); +const swatchSolid = css({ width: "4", height: "0.5", borderRadius: "full" }); +const legendLabelSm = css({ + textStyle: "xxs", + color: "fg.max", + letterSpacing: "[0.2px]", +}); +const legendLabelMd = css({ + textStyle: "xs", + fontWeight: "medium", + color: "fg.heading", + letterSpacing: "[0.12px]", +}); + +export const ClickableMonthTick = ({ + x: xValue, + y: yValue, + payload, + months, + onMonthClick, +}: { + x?: number; + y?: number; + payload?: { value?: string | number }; + months: Array<{ month: string; label: string }>; + onMonthClick?: (month: string) => void; +}) => { + const label = String(payload?.value ?? ""); + const month = months.find((month2) => month2.label === label)?.month; + const clickable = onMonthClick && month; + const handleClick = clickable + ? (event: MouseEvent) => { + event.stopPropagation(); + onMonthClick(month); + } + : undefined; + const handleKeyDown = clickable + ? (event: KeyboardEvent) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + event.stopPropagation(); + onMonthClick(month); + } + } + : undefined; + + return ( + + + {label} + + + ); +}; + +export const CustomDot = ({ + cx, + cy, + color, + payload, + onMonthClick, +}: { + cx?: number; + cy?: number; + color: string; + payload?: { month?: string }; + onMonthClick?: (month: string) => void; +}) => { + if (cx == null || cy == null) { + return null; + } + const month = payload?.month; + const handleClick = + onMonthClick && month + ? (event: MouseEvent) => { + event.stopPropagation(); + onMonthClick(month); + } + : undefined; + const handleKeyDown = + onMonthClick && month + ? (event: KeyboardEvent) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + event.stopPropagation(); + onMonthClick(month); + } + } + : undefined; + return ( + + + + + + ); +}; + +/** + * Legend swatch + label. `size="sm"` matches the dense trend-chart legend; + * `size="md"` matches the savings-calculator legend. `dashed` renders a + * dashed reference line swatch instead of a solid bar. + */ +export const LegendLine = ({ + color, + label, + dashed, + size = "sm", +}: { + color: string; + label: string; + dashed?: boolean; + size?: "sm" | "md"; +}) => { + return ( +
+
+ + + {label} + +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/chart-theme.ts b/apps/hash-frontend/src/pages/supply-chain/shared/chart-theme.ts new file mode 100644 index 00000000000..758412613e4 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/chart-theme.ts @@ -0,0 +1,51 @@ +import { token } from "@hashintel/ds-helpers/tokens"; + +/** + * Central chart color theme. Every value is read from a ds-components token + * via `token.var(...)` (→ `var(--colors-…)`), so charts follow the design system + * and theme with it — no literal hex in chart components. + * + * Roles map to the supply-chain chart palette: + * axis/grid/ticks -> neutral `fg`/`bd`; series -> `status.*` + a yellow mean line. + * + * Scope: the `--colors-*` vars are defined inside `.hash-ds-root`, so charts + * must render inside the supply-chain layout or a portal container within it. + */ +export const chartTheme = { + /** Axis lines, gridlines, and tick labels. */ + axis: { + /** `axisLine`/tick line stroke (was `#dfdfdf`). */ + line: token.var("colors.bd.subtle"), + /** Standard tick label (was `#646464`). */ + tick: token.var("colors.fg.muted"), + /** Emphasised tick label (was `#000`). */ + tickStrong: token.var("colors.fg.heading"), + }, + /** Cartesian gridlines (was `#dfdfdf` / faint). */ + grid: token.var("colors.bd.subtle"), + /** Dashed reference/assumption line (was `#989898`). */ + reference: token.var("colors.fg.subtle"), + /** Recharts tooltip surface (opaque — may render in a portal). */ + tooltip: { + bg: token.var("colors.bgSolid.min"), + border: token.var("colors.bd.subtle"), + text: token.var("colors.fg.body"), + }, + /** Data series, by semantic role. */ + series: { + /** "Under assumption" / median / info (was `#64ade6`). */ + info: token.var("colors.status.info.bg.solid"), + /** Mean line (was `#ffce5c`). */ + mean: token.var("colors.yellow.s90"), + /** "Above assumption" / over (was `#ff9c5e`). */ + warning: token.var("colors.status.warning.bg.solid"), + /** Worst band (was `#ff8870`). */ + critical: token.var("colors.status.error.bg.solid"), + /** Positive/"reduced" series (was teal `#3cc3b3`). */ + success: token.var("colors.status.success.bg.solid"), + /** Neutral/secondary series. */ + neutral: token.var("colors.fg.subtle"), + }, +} as const; + +export type ChartTheme = typeof chartTheme; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/cost.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/cost.test.ts new file mode 100644 index 00000000000..545e5e01f67 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/cost.test.ts @@ -0,0 +1,131 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { + DEFAULT_STORAGE_COST, + DEFAULT_WACC, + computeDailyCost, + computeMonthlyCost, + computePeriodCost, + costRatePerKgDay, + formatCost, + formatNumber, +} from "./cost"; + +// Characterization tests: pin the current cost-model + formatting behaviour +// before the contract refactor. These are pure numeric functions. + +describe("costRatePerKgDay", () => { + it("combines WACC interest and storage at the documented rate", () => { + // 100 * (0.10/365) + 0.4/1000 + expect( + costRatePerKgDay(100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeCloseTo(100 * (0.1 / 365) + 0.4 / 1000, 10); + }); + + it("treats a null unit price as zero interest (storage only)", () => { + expect( + costRatePerKgDay(null, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeCloseTo(DEFAULT_STORAGE_COST / 1000, 10); + }); +}); + +describe("computeMonthlyCost / computeDailyCost", () => { + it("multiplies kg-days by the per-kg-day rate", () => { + const rate = costRatePerKgDay(100, DEFAULT_WACC, DEFAULT_STORAGE_COST); + expect( + computeMonthlyCost(1000, 100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeCloseTo(1000 * rate, 8); + }); + + it("returns null when an input is missing", () => { + expect( + computeMonthlyCost(null, 100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeNull(); + expect( + computeMonthlyCost(1000, null, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeNull(); + expect( + computeDailyCost(null, 100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeNull(); + }); +}); + +describe("computePeriodCost", () => { + const months = [ + { total_kg_days: 1000 }, + { total_kg_days: 500 }, + { total_kg_days: 2500 }, + ]; + + it("sums computeMonthlyCost over the buckets", () => { + const rate = costRatePerKgDay(100, DEFAULT_WACC, DEFAULT_STORAGE_COST); + expect( + computePeriodCost(months, 100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeCloseTo((1000 + 500 + 2500) * rate, 6); + }); + + it("equals the manual per-bucket reduce (the dedup invariant)", () => { + const manual = months.reduce( + (sum, month) => + sum + + (computeMonthlyCost( + month.total_kg_days, + 100, + DEFAULT_WACC, + DEFAULT_STORAGE_COST, + ) ?? 0), + 0, + ); + expect( + computePeriodCost(months, 100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBeCloseTo(manual, 6); + }); + + it("returns 0 for null/empty monthly or missing unit price", () => { + expect( + computePeriodCost(null, 100, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBe(0); + expect(computePeriodCost([], 100, DEFAULT_WACC, DEFAULT_STORAGE_COST)).toBe( + 0, + ); + // null unit price -> each bucket contributes null -> treated as 0 + expect( + computePeriodCost(months, null, DEFAULT_WACC, DEFAULT_STORAGE_COST), + ).toBe(0); + }); +}); + +describe("formatCost / formatNumber", () => { + // Pin locale so thousands/decimal separators are deterministic. + afterEach(() => vi.unstubAllGlobals()); + function withLocale() { + vi.stubGlobal("navigator", { language: "en-US" }); + } + + it("formats a 2dp currency with its symbol", () => { + withLocale(); + expect(formatCost(1234.5, "CHF")).toBe("CHF 1,234.50"); + }); + + it("rounds zero-decimal currencies (JPY/CNY) to whole units", () => { + withLocale(); + expect(formatCost(1234.5, "JPY")).toBe("¥1,235"); + }); + + it("renders compact magnitudes", () => { + withLocale(); + expect(formatCost(2_500_000, "USD", { compact: true })).toBe("$2.5m"); + expect(formatNumber(1500, { compact: true })).toBe("1.5k"); + }); + + it("falls back to USD when no currency is supplied", () => { + withLocale(); + expect(formatCost(2500, null, { compact: true })).toBe("$2.5k"); + }); + + it("renders a dash for null", () => { + withLocale(); + expect(formatCost(null, "USD")).toBe("–"); + expect(formatNumber(null)).toBe("–"); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/cost.ts b/apps/hash-frontend/src/pages/supply-chain/shared/cost.ts new file mode 100644 index 00000000000..1ad356b1d7a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/cost.ts @@ -0,0 +1,183 @@ +import { createContext, useContext } from "react"; + +export const DEFAULT_WACC = 0.1; +export const DEFAULT_STORAGE_COST = 0.4; // currency units/tonne/day +export const DEFAULT_CURRENCY = "USD"; + +interface CostParamsCtx { + currency: string; + setAnalysisSettings: ( + settings: + | { currency?: string | null; storage_cost?: number | null } + | null + | undefined, + ) => void; + waccRate: number; + setWaccRate: (rate: number) => void; + storageCost: number; + setStorageCost: (cost: number) => void; +} + +export const CostParamsContext = createContext({ + currency: DEFAULT_CURRENCY, + setAnalysisSettings: () => {}, + waccRate: DEFAULT_WACC, + setWaccRate: () => {}, + storageCost: DEFAULT_STORAGE_COST, + setStorageCost: () => {}, +}); + +export function useCostParams() { + return useContext(CostParamsContext); +} + +interface OutlierCtx { + excludeOutliers: boolean; + setExcludeOutliers: (exclude: boolean) => void; +} + +export const OutlierContext = createContext({ + excludeOutliers: true, + setExcludeOutliers: () => {}, +}); + +export function useOutlierSetting() { + return useContext(OutlierContext); +} + +/** Cost rate per kg per day given current WACC and storage params. */ +export function costRatePerKgDay( + unitPrice: number | null | undefined, + waccRate: number, + storageCost: number, +): number { + return (unitPrice ?? 0) * (waccRate / 365) + storageCost / 1000; +} + +/** Recompute monthly total cost from kg-days and unit price. */ +export function computeMonthlyCost( + totalKgDays: number | null | undefined, + unitPrice: number | null | undefined, + waccRate: number, + storageCost: number, +): number | null { + if (totalKgDays == null || unitPrice == null) { + return null; + } + return totalKgDays * costRatePerKgDay(unitPrice, waccRate, storageCost); +} + +/** A monthly bucket carrying the kg-days needed to recompute carrying cost. */ +interface KgDayBucket { + total_kg_days?: number | null; +} + +/** + * Sum a node's carrying cost over its monthly buckets: the period total is + * `Σ computeMonthlyCost(bucket.total_kg_days, unitPrice, wacc, storage)`. + * Single source of truth for the ~10 inline reduce copies across the app. + */ +export function computePeriodCost( + monthly: KgDayBucket[] | null | undefined, + unitPrice: number | null | undefined, + waccRate: number, + storageCost: number, +): number { + if (!monthly) { + return 0; + } + return monthly.reduce( + (sum, month) => + sum + + (computeMonthlyCost( + month.total_kg_days, + unitPrice, + waccRate, + storageCost, + ) ?? 0), + 0, + ); +} + +/** Recompute daily carrying cost from mean quantity and unit price. */ +export function computeDailyCost( + meanQty: number | null | undefined, + unitPrice: number | null | undefined, + waccRate: number, + storageCost: number, +): number | null { + if (meanQty == null || unitPrice == null) { + return null; + } + return meanQty * costRatePerKgDay(unitPrice, waccRate, storageCost); +} + +const CURRENCY_SYMBOLS: Record = { + JPY: "¥", + USD: "$", + EUR: "€", + CNY: "¥", + CHF: "CHF ", +}; + +/** Resolve the active locale for all number/date formatting. Single source of truth. */ +export function getUserLocale(): string { + return navigator.language; +} + +function localiseNumber( + value: number, + opts?: { maximumFractionDigits?: number; minimumFractionDigits?: number }, +): string { + return new Intl.NumberFormat(getUserLocale(), opts).format(value); +} + +export function formatCost( + value: number | null | undefined, + currency: string | null, + opts?: { compact?: boolean }, +): string { + if (value == null) { + return "–"; + } + const activeCurrency = currency ?? DEFAULT_CURRENCY; + const sym = CURRENCY_SYMBOLS[activeCurrency] ?? ""; + if (opts?.compact) { + const abs = Math.abs(value); + if (abs >= 1_000_000) { + return `${sym}${localiseNumber(value / 1_000_000, { maximumFractionDigits: 1 })}m`; + } + if (abs >= 1_000) { + return `${sym}${localiseNumber(value / 1_000, { maximumFractionDigits: 1 })}k`; + } + return `${sym}${localiseNumber(Math.round(value))}`; + } + if (activeCurrency === "JPY" || activeCurrency === "CNY") { + return `${sym}${localiseNumber(Math.round(value))}`; + } + return `${sym}${localiseNumber(value, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; +} + +/** Format a plain number (non-currency) respecting user locale. */ +export function formatNumber( + value: number | null | undefined, + opts?: { + maximumFractionDigits?: number; + minimumFractionDigits?: number; + compact?: boolean; + }, +): string { + if (value == null) { + return "–"; + } + if (opts?.compact) { + const abs = Math.abs(value); + if (abs >= 1_000_000) { + return `${localiseNumber(value / 1_000_000, { maximumFractionDigits: 1 })}m`; + } + if (abs >= 1_000) { + return `${localiseNumber(value / 1_000, { maximumFractionDigits: 1 })}k`; + } + } + return localiseNumber(value, opts); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/data-table.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/data-table.tsx new file mode 100644 index 00000000000..c17efe3d020 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/data-table.tsx @@ -0,0 +1,161 @@ +import { flexRender, type Table } from "@tanstack/react-table"; + +import { Icon } from "@hashintel/ds-components"; +import { css } from "@hashintel/ds-helpers/css"; + +import type { ReactNode } from "react"; + +/** + * Panda-styled presentation wrapper around a `@tanstack/react-table` instance + * (C4). The caller owns columns/data/sorting/filtering (`useReactTable`); this + * renders the markup with C3 tokens + sortable-header affordances. Replaces the + * hand-rolled table chrome in `data-table-section.tsx`. + */ +interface DataTableProps { + table: Table; + /** Shown when there are no rows. */ + emptyState?: ReactNode; + className?: string; +} + +const tableStyles = css({ + width: "full", + borderCollapse: "collapse", + textStyle: "sm", + lineHeight: "normal", +}); + +const thStyles = css({ + paddingX: "3", + paddingY: "2", + textAlign: "left", + textStyle: "xs", + fontWeight: "medium", + color: "fg.muted", + whiteSpace: "nowrap", + borderBottomWidth: "1px", + borderBottomStyle: "solid", + borderBottomColor: "bd.subtle", +}); + +const sortableStyles = css({ + cursor: "pointer", + userSelect: "none", + _hover: { color: "fg.body" }, +}); + +const thInnerStyles = css({ + display: "inline-flex", + alignItems: "center", + gap: "1", +}); + +const sortIconStyles = css({ color: "fg.muted" }); + +const tdStyles = css({ + paddingX: "3", + paddingY: "1.5", + color: "fg.body", + borderBottomWidth: "1px", + borderBottomStyle: "solid", + borderBottomColor: "bd.subtle", +}); + +const rowStyles = css({ + transition: "colors", + _hover: { bg: "bg.subtle" }, +}); + +const emptyStyles = css({ + paddingX: "3", + paddingY: "6", + textAlign: "center", + textStyle: "sm", + color: "fg.subtle", +}); + +export const DataTable = ({ + table, + emptyState, + className, +}: DataTableProps) => { + const rows = table.getRowModel().rows; + const columnCount = table.getAllLeafColumns().length; + + return ( + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + const canSort = header.column.getCanSort(); + const sorted = header.column.getIsSorted(); + const toggleSort = header.column.getToggleSortingHandler(); + return ( + + ); + })} + + ))} + + + {rows.length === 0 ? ( + + + + ) : ( + rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + ))} + + )) + )} + +
+ {header.isPlaceholder ? null : ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + {sorted === "asc" && ( + + )} + {sorted === "desc" && ( + + )} + + )} +
+ {emptyState ?? "No data"} +
+ {flexRender(cell.column.columnDef.cell, cell.getContext())} +
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/data.ts b/apps/hash-frontend/src/pages/supply-chain/shared/data.ts new file mode 100644 index 00000000000..3ce7e96e623 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/data.ts @@ -0,0 +1,170 @@ +import { fetchArtifactJson } from "../../../shared/analysis-client"; +import { + ensureGraphStats, + ensureNodeStats, + ensureStepStats, +} from "./normalize-contract"; +import { + fetchGraph as fetchAnalysisGraph, + fetchProducts as fetchAnalysisProducts, + fetchSiteSummary as fetchAnalysisSiteSummary, + fetchSites as fetchAnalysisSites, + fetchStepDetail as fetchAnalysisStepDetail, + fetchSupplierPerformance as fetchAnalysisSupplierPerformance, +} from "./supply-chain-analysis-requests"; + +import type { + Product, + GraphData, + StepDetail, + SiteData, + SiteSupplierPerformance, + SiteSummary, +} from "./types"; +import type { WebId } from "@blockprotocol/type-system"; + +/** A selectable site with its data slug and display name. */ +export interface SiteRef { + slug: string; + name: string; +} + +let activeWebId: WebId | null = null; + +/** + * Configure the workspace web whose published analysis artifacts back the + * supply-chain views. All data reads go through HASH's analysis gateway. + */ + +/** + * Site-wide supplier performance. Cached for the session; missing optional + * artifacts resolve to `null`, so the cache holds at most one resolved promise. + */ + +/** + * Session cache for `fetchSiteData`, keyed by web + site + product set. A + * rejected promise is evicted so a later mount can retry. + */ +const siteDataCache = new Map>(); +let supplierPerformanceCache: Promise | null = + null; +export function configureDataSource({ + scope, +}: { + scope: WebId | string; +}): void { + activeWebId = scope as WebId; + supplierPerformanceCache = null; + siteDataCache.clear(); +} +const getActiveWebId = (): WebId => { + if (!activeWebId) { + throw new Error("Supply-chain data source is not configured."); + } + return activeWebId; +}; +export function fetchProducts(): Promise { + return fetchAnalysisProducts(getActiveWebId()) as Promise; +} +/** + * Site registry used to populate the scope picker and resolve display names. + * Returns an empty list when unavailable. + */ export function fetchSites(): Promise { + return fetchAnalysisSites(getActiveWebId()); +} +/** + * Load a product graph. With the v1 data contract the generator emits the + * final node/segment shape, so the loader is a straight typed fetch with a + * normalization pass for older optional fields. + */ export function fetchGraph(productId: string): Promise { + return fetchAnalysisGraph(getActiveWebId(), productId).then( + ensureGraphStats, + ); +} +export async function fetchAllGraphs(products: Product[]): Promise { + const graphs = await Promise.all( + products.map((product) => + fetchGraph(product.id).then((graph) => ({ product, graph })), + ), + ); + return { + analysis_settings: + graphs.find(({ graph }) => graph.analysis_settings)?.graph + .analysis_settings ?? null, + graphs, + }; +} +export function fetchSupplierPerformance(): Promise { + if (supplierPerformanceCache) { + return supplierPerformanceCache; + } + supplierPerformanceCache = + fetchAnalysisSupplierPerformance(getActiveWebId()); + return supplierPerformanceCache; +} +export function fetchStepDetail( + productId: string, + stepId: string, +): Promise { + return fetchAnalysisStepDetail( + getActiveWebId(), + productId, + stepId, + ).then(ensureStepStats); +} +/** + * Site overview summary. Precomputed per site so the overview never has to + * fetch every product's full graph. + */ export function fetchSiteSummary( + siteId: string, +): Promise { + return fetchAnalysisSiteSummary(getActiveWebId(), siteId); +} +/** + * Build the `SiteData` the overview consumes. Prefers the precomputed + * `site/{id}/summary.json` (one request, full v1 nodes embedded) and adapts it + * into the `{ graphs: [{ product, graph }] }` shape the aggregation helpers + * expect. Falls back to fetching every product's full graph only when no + * summary is published. + */ export async function fetchSiteData( + siteId: string, + products: Product[], +): Promise { + const summary = await fetchSiteSummary(siteId); + if (summary && summary.products.length > 0) { + return { + analysis_settings: summary.analysis_settings ?? null, + graphs: summary.products.map((product) => ({ + product: { id: product.id, name: product.name, material: "" }, + graph: { + schema_version: summary.schema_version, + product_id: product.id, + product_name: product.name, + nodes: product.nodes.map(ensureNodeStats), + edges: [], + pipeline_summary: {}, + }, + })), + }; + } + return fetchAllGraphs(products); +} +export function fetchSiteDataCached( + siteId: string, + products: Product[], +): Promise { + const key = `${getActiveWebId()}::${siteId}::${products + .map((product) => product.id) + .sort() + .join(",")}`; + const cached = siteDataCache.get(key); + if (cached) { + return cached; + } + const pending = fetchSiteData(siteId, products); + siteDataCache.set(key, pending); + pending.catch(() => siteDataCache.delete(key)); + return pending; +} + +export { fetchArtifactJson }; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/detail-date-key.ts b/apps/hash-frontend/src/pages/supply-chain/shared/detail-date-key.ts new file mode 100644 index 00000000000..10e19fc588c --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/detail-date-key.ts @@ -0,0 +1,47 @@ +import type { DetailRows } from "./types"; + +/** + * Ordered fallback for which detail-row column holds the observation date when + * a step does not carry an explicit `ref_date_col`. Union of every + * per-dimension date column the views may key on (timing, dwell, consumption, + * outbound), ordered so the completion/event date wins when several are + * present. + */ +export const DETAIL_DATE_KEY_PREFERENCE = [ + "finish_date", + "confirmed_finish", + "end", + "prod_receipt_date", + "production_receipt_date", + "qa_entry_date", + "arrival_date", + "qa_release_date", + "outbound_date", + "receipt_date", + "consumption_date", + "first_gr_date", + "last_gr_date", + "po_date", + "promised_date", + "ship_date", + "departure_date", + "sched_start", + "posting_date", + "start", +]; + +/** + * Resolve the detail-row date column. The canonical answer is the step's + * `ref_date_col` (emitted by the generator for every step); the preference + * list is only a fallback for payloads that don't carry one. + */ +export function detailDateKeyFromColumns( + rows: DetailRows, + refDateCol?: string | null, +): string | null { + const keys = new Set(rows.columns.map((column) => column.key)); + if (refDateCol && keys.has(refDateCol)) { + return refDateCol; + } + return DETAIL_DATE_KEY_PREFERENCE.find((key) => keys.has(key)) ?? null; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content.tsx new file mode 100644 index 00000000000..4473210f3b1 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content.tsx @@ -0,0 +1,65 @@ +import { opportunityBriefSection } from "./docs-content/opportunity-brief"; +import { productOverviewSection } from "./docs-content/product-overview"; +import { settingsSection } from "./docs-content/settings"; +import { siteOverviewSection } from "./docs-content/site-overview"; +import { stepDetailDoc } from "./docs-content/step-detail"; +import { dwellDoc } from "./docs-content/step-dwell"; +import { procurementDoc } from "./docs-content/step-procurement"; +import { productionDoc } from "./docs-content/step-production"; +import { qaDoc } from "./docs-content/step-qa"; +import { transitDoc } from "./docs-content/step-transit"; + +import type { StepType } from "../types"; +import type { DocSectionDef, DocSectionId, DocTarget } from "./docs-types"; + +const stepsSection: DocSectionDef = { + id: "steps", + title: "Steps", + entries: [ + stepDetailDoc, + procurementDoc, + dwellDoc, + productionDoc, + qaDoc, + transitDoc, + ], +}; + +/** The full docs navigation tree, in sidebar order. */ +export const DOC_SECTIONS: DocSectionDef[] = [ + siteOverviewSection, + productOverviewSection, + stepsSection, + opportunityBriefSection, + settingsSection, +]; + +export type { DocSectionId, DocTarget }; + +/** + * Map a value-chain step type onto the docs target to open from the step + * slideover. Dwell variants share the single Dwell entry but deep-link to the + * matching span anchor. + */ +export function stepDocTarget(type: StepType): DocTarget { + switch (type) { + case "procurement": + return { section: "steps", sub: "procurement" }; + case "production": + return { section: "steps", sub: "production" }; + case "qa_hold": + return { section: "steps", sub: "qa" }; + case "transit": + return { section: "steps", sub: "transit" }; + case "raw_material_dwell": + return { section: "steps", sub: "dwell-raw-material" }; + case "intermediate_dwell": + return { section: "steps", sub: "dwell-intermediate" }; + case "post_qa_ship": + return { section: "steps", sub: "dwell-post-qa-ship" }; + case "destination_dwell": + return { section: "steps", sub: "dwell-destination" }; + default: + return { section: "steps", sub: "procurement" }; + } +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/opportunity-brief.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/opportunity-brief.tsx new file mode 100644 index 00000000000..b33b86600d0 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/opportunity-brief.tsx @@ -0,0 +1,105 @@ +import { Lead, P, H4, Term, UL, LI, Note, CrossRef } from "../docs-primitives"; + +import type { DocSectionDef } from "../docs-types"; + +export const opportunityBriefSection: DocSectionDef = { + id: "opportunity-brief", + title: "Opportunity brief", + entries: [ + { + id: "opportunity-brief", + title: "Opportunity brief", + render: () => ( + <> + + Opportunity briefs are printable investigation reports opened from + the site opportunities table or the step detail panel. They turn one + flagged step into a structured evidence pack. + +

+ There are two brief types: dwell cost reduction and planning + parameter calibration. Both use the same filtered step evidence, + time range, outlier setting and cost assumptions that are active in + the app. +

+ +

Brief types

+
    +
  • + Dwell cost reduction briefs focus on inventory + carrying cost. They show current period cost, annualised cost, + scenario savings and the operational evidence behind the wait. +
  • +
  • + Planning calibration briefs focus on whether the + planning parameter still matches observed timing. They compare + current plan, P95, median, mean and the share of batches exceeding + plan. +
  • +
+ +

Report sections

+
    +
  • + Executive summary explains why the opportunity fired + and summarises the prize or calibration decision. +
  • +
  • + Opportunity diagnosis lists the main diagnostic + statements and confidence notes for the evidence. +
  • +
  • + Potential impact or calibration options shows + dwell-reduction scenarios or planning service-level options. +
  • +
  • + End-to-end leverage appears on dwell briefs when the + step can be connected to traceable batch pipelines. It estimates + whether reducing the wait would move finished good end-to-end + timing. +
  • +
  • + First-use dwell appears when the brief can identify + how early materials were ordered or intermediates were produced + before first downstream use. +
  • +
  • + Supplier OTIF and Yield and consumption{" "} + appear when supplier or production side evidence is available for + the step. +
  • +
  • + Distribution and evidence contains the box plot, + histogram, monthly trend, statistics, evidence-quality flags and + largest contributing records. +
  • +
  • + Recommended next steps gives investigation checks and + step-type-specific prompts for follow-up. +
  • +
+ +

Evidence exports and print

+

+ Use Evidence CSV to export the records behind the brief and Print / + Save as PDF to share the report. Before acting on the + recommendation, validate the source rows, affected batches, + materials and months in the operational system. +

+ + A brief is an investigation aid, not an automatic process + prescription. Savings assume carrying cost scales with kg-days, and + planning recommendations still need business review for + service-level tolerance. See{" "} + + Overview & opportunities + {" "} + for how opportunities are selected. + + + ), + }, + ], +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/product-overview.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/product-overview.tsx new file mode 100644 index 00000000000..db9a8be25df --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/product-overview.tsx @@ -0,0 +1,279 @@ +import { Lead, P, H4, Term, UL, LI, Note, CrossRef } from "../docs-primitives"; + +import type { DocSectionDef } from "../docs-types"; + +export const productOverviewSection: DocSectionDef = { + id: "product-overview", + title: "Product overview", + entries: [ + { + id: "category-view", + title: "Category view", + render: () => ( + <> + + The category view lays out a product's value chain as cards + grouped by step category — procurement, dwell, production, QA + and logistics. + +

+ Each card shows the step's headline timing and a badge + indicating how it compares to its planning parameter, so you can + scan a whole product's chain at a glance. Selecting a card + opens that step's detail. +

+

Header KPIs and navigation

+

+ The product selector in the header switches between finished goods. + The KPI chips below it show traceable end-to-end mean, traceable + end-to-end median and total dwell carrying cost for the selected + time range when those values are available. +

+

Step categories

+
    +
  • + Procurement measures purchase-order lead time for + bought inputs, either to first receipt or full receipt depending + on the procurement-basis setting. +
  • +
  • + Dwell measures waiting time between operational + milestones: raw material receipt to consumption, intermediate + production to consumption, QA release to shipment, or hub arrival + to onward shipment. +
  • +
  • + Production measures manufacturing duration. Where + available, production cards are normalised to a reference batch + size so campaigns of different sizes are comparable. +
  • +
  • + QA measures the hold between production finish and + quality release. +
  • +
  • + Logistics measures transit after release, either + direct to the customer or through a destination hub. +
  • +
+

Reading a card

+
    +
  • + Headline days are the selected measure from settings + (median, mean, P75 or P95) for the current time range. +
  • +
  • + Mini distribution is a compact box plot: the grey + whiskers span min to max, the shaded box is P25 to P75, the blue + tick is median and the yellow tick is mean. +
  • +
  • + Planning badge shows the planning parameter in days. + Green means the selected measure is at least 10% below plan, amber + means between 90% and 120% of plan, and red means more than 20% + above plan. +
  • +
  • + Percent badge shows how far the selected measure is + over or under the planning parameter. +
  • +
  • + Cost badge appears on dwell cards when carrying-cost + inputs are available. It estimates inventory carrying cost over + the selected time range using the settings panel's WACC and + storage assumptions. +
  • +
  • + R and C badges appear on production cards when yield + or consumption data is available. R is receipt ratio versus order + quantity; C is material consumption variance versus expectation. +
  • +
  • + Event count shows how many observations feed the + card. A warning triangle means the sample is small, so the + statistic should be treated as directional. +
  • +
+ + ), + }, + { + id: "canvas-view", + title: "Canvas view", + render: () => ( + <> + + The canvas view draws the same value chain as a process graph, + showing how materials and steps connect from inputs through to the + finished good. + +

Node colour

+

+ Each step node is coloured by how its headline timing compares to + the planning parameter: +

+
    +
  • + Green — at least 10% below plan. +
  • +
  • + Amber — between 90% and 120% of plan. +
  • +
  • + Red — more than 20% above plan. +
  • +
  • + Grey — no planning parameter available to + compare against. +
  • +
+ + ), + }, + { + id: "e2e-pipeline", + title: "End-to-end pipeline", + render: () => ( + <> + + The pipeline at the foot of the product page traces each + finished-good batch individually, from the earliest procurement of + any input through to the route endpoint, and decomposes the journey + into four segments. + +

+ Unlike the step cards (which pool statistics per step type), the + pipeline follows real batches and computes segment durations from + each batch's own milestone dates. The four segments are: +

+
    +
  • + Procurement to production start covers the + pre-production lead-in: bought inputs, raw-material availability + and any waiting before the finished-good campaign begins. +
  • +
  • + Production start to production finish covers upstream + production chains, intermediate waits and the final finished-good + campaign. Parallel upstream paths are represented by the path that + governs each batch's production-start timing. +
  • +
  • + Production finish to QA release is the quality hold + after production completes. +
  • +
  • + QA release to customer covers post-QA dwell and + transport to the route endpoint: customer arrival for direct + external-customer shipments; hub dispatch for routes that go via a + hub unless a measured hub-to-customer transport end is available). +
  • +
+

+ A route picker switches between delivery routes (direct or via a + hub), and a coverage indicator shows how many batches had a complete + enough trace to be included. The pipeline filters batches by the + route endpoint date, so its population can differ from the step + cards, which each anchor to their own event date. +

+

+ Shipment step cards can count more than one delivery for the same + batch. The pipeline keeps one route per batch, so direct-shipment + observation counts may be higher than the number of batches shown on + the direct route. +

+

Mean, median and segment toggles

+

+ The waterfall shows mean and median totals for the selected route. + Segment chips in the legend can be switched off to focus the + waterfall, KPIs and simulator on the remaining portion of the + journey. Procurement is off by default in the simulator view because + its detailed improvement math is handled in the step-level + procurement and dwell analyses. +

+ + ), + }, + { + id: "what-if", + title: "What-if simulator", + render: () => ( + <> + + Expanding the pipeline opens a what-if simulator: per-step cap + controls let you ask “if we trimmed unusually long occurrences + of this step, how much would end-to-end time shrink, and what would + it save?” + +

+ The answer is not simple addition. Steps on parallel upstream paths + only help when they are on the path that actually governs the + campaign, and trimming a step past the point where another path + becomes limiting yields nothing further. Serial post-production + steps such as QA hold, transit and destination dwell reduce the + total directly when their long observations are capped. +

+

How this works

+

+ Each lever caps that step's batch durations at the selected + checkpoint: Max, P95, P75, median, P25 or Exclude. Durations below + the cap are unchanged; durations above it are clipped to the cap + before the KPIs and dashed simulated bars are recomputed. +

+

+ For upstream production chains, the simulator recomputes the full + set of paths for each batch and uses the longest remaining path as + the production-start driver. For finished-good production, QA hold + and post-QA logistics, the simulator treats the steps as serial and + subtracts the capped tail from the relevant segment. +

+

Controls

+
    +
  • + Cap checkpoints — each lever caps a step at a + historical checkpoint (P95, P75, median, P25, or exclude + entirely). The default is uncapped. A cap only clips occurrences + above it; shorter ones are unchanged. +
  • +
  • + Lever summary — each card shows the step's + median and mean, the cap status, the number of observations + shortened by an active cap and an open-step icon for drilling into + the underlying detail panel. +
  • +
  • + Not in current recipe — a warning badge means + the step appears in historical traces but is not reachable in the + current BOM or recipe, so it may not represent future production + unless the old recipe is used again. +
  • +
  • + Segment toggle — the legend chips below the + waterfall switch whole segments in or out of the totals, KPIs and + lever list. The selection is saved in the URL so it can be shared. +
  • +
  • + Route scope — each simulation runs against one + delivery route; the lever list reflects the steps ranked for that + route. +
  • +
+

+ Headline KPIs show simulated end-to-end mean and median, days saved, + and an annualised cost saving recomputed live from the cost + assumptions in{" "} + + Settings & controls + + . +

+ + The simulator is a directional planning tool. It assumes capped + durations can be realised operationally, but it does not reschedule + campaigns, model plant capacity or change shipment cadence. + + + ), + }, + ], +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/settings.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/settings.tsx new file mode 100644 index 00000000000..631b2abe536 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/settings.tsx @@ -0,0 +1,120 @@ +import { + Lead, + P, + H4, + Term, + UL, + LI, + Anchor, + SettingRow, + CrossRef, +} from "../docs-primitives"; + +import type { DocSectionDef } from "../docs-types"; + +export const settingsSection: DocSectionDef = { + id: "settings", + title: "Settings & controls", + entries: [ + { + id: "settings", + title: "Settings & controls", + render: () => ( + <> + + These controls live behind the settings cog and apply consistently + across the site overview, product overview and step detail. They are + encoded in the URL, so a configured view can be shared or reloaded + without losing its settings. + + + + + The cost-of-capital rate applied to inventory value when computing + dwell carrying cost. Raising it increases every carrying-cost + figure proportionally. + + + + + The physical storage rate per tonne per day added on top of the + cost of capital when computing dwell carrying cost. + + + + + The headline statistic used for step timing: median, mean, P75 or + P95. It drives the step-card headline, the over/under-plan badges, + the site planning and dwell “observed” columns and the + trends. It does not change the named statistics tables in the step + detail, which always show explicit values. + + + + + Whether procurement lead time is measured to the{" "} + first goods receipt or to the full{" "} + (final) receipt that completes the order. See the scope note + below. + + + + + The 3m / 6m / 12m window. Each view filters by its own relevant + event date, so the same window can select slightly different + populations in different views. + + + + + Drops values outside a Tukey 1.5x IQR fence. For each timing, + receipt-ratio or consumption series, the app computes Q1 and Q3, + calculates the interquartile range (IQR = Q3 - Q1), then excludes + points below Q1 - 1.5x IQR or above Q3 + 1.5x IQR. Statistics and + monthly timing are recomputed from the kept observations. + + + +

Where settings do not apply

+
    +
  • + Procurement basis affects procurement steps only.{" "} + First vs full receipt changes the procurement lead-time series + wherever it appears, including the procurement rows that feed the + site planning table and opportunities. Every non-procurement step + type ignores it — their timings are not derived from + purchase-order receipts, so there is nothing for the basis to + switch between. +
  • +
  • + Planning opportunities key off P95, not the measure.{" "} + The planning-deviation opportunities compare the P95 of observed + timing against the planning parameter, so they do not move when + the headline{" "} + + measure + {" "} + is switched between median and mean. +
  • +
  • + Outlier fences are series-specific. Timing, + receipt-ratio, aggregate consumption and component consumption + each get their own IQR fence. Procurement's first-receipt and + full-receipt timing series are also filtered independently. +
  • +
+ +

Site-only controls

+

+ The site overview adds two of its own controls — a category + filter and an exclude-low-samples toggle. See{" "} + + Site filters & controls + + . +

+ + ), + }, + ], +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/site-overview.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/site-overview.tsx new file mode 100644 index 00000000000..94eaafc9670 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/site-overview.tsx @@ -0,0 +1,210 @@ +import { Lead, P, H4, Term, UL, LI, Note, CrossRef } from "../docs-primitives"; + +import type { DocSectionDef } from "../docs-types"; + +export const siteOverviewSection: DocSectionDef = { + id: "site-overview", + title: "Site overview", + entries: [ + { + id: "overview-opportunities", + title: "Overview & opportunities", + render: () => ( + <> + + The site view brings every product made at the plant into one + dashboard, so the highest-impact timing and cost issues surface + regardless of which product they belong to. + +

+ Steps shared across products (such as a raw material used by several + finished goods) appear once, tagged with every product that uses + them, so their cost is not double-counted. Product-specific steps + stay attributed to their product. +

+

Opportunities

+

+ The opportunities table at the top ranks the most actionable + findings across the site. Each opportunity is one of: +

+
    +
  • + Dwell cost — a dwell step carrying a material + cost over the selected period. It appears when median dwell is at + least 7 days and the selected-period carrying cost is at least + 5,000 in the site currency. +
  • +
  • + Planning over / under — observed timing sitting + above or below the planning parameter for the step. It appears + when P95 is at least 10% above or below plan. +
  • +
+

+ Each row shows its impact, supporting evidence and a sample-size + confidence label, and can be marked read or unread and annotated + with status updates to track investigation status. Selecting a row + opens that step's detail. +

+

Investigation workflow

+

+ Mark read hides an opportunity from the default list once it has + been reviewed; Show read brings completed items back. The Status + action records investigation started, updates, conclusions, + infeasible rejections or data-issue rejections. Status history is + keyed to the step/opportunity target and is also visible from the + step detail panel. +

+

+ The Brief action opens a printable{" "} + + Opportunity brief + {" "} + with the evidence, scenarios and recommended checks behind the row. +

+ + Dwell opportunity qualification uses median dwell and carrying cost; + planning opportunity qualification uses P95. These are fixed gates, + so changing the global Measure setting does not change which + opportunities appear. + + + ), + }, + { + id: "monthly-carry-cost", + title: "Monthly carry-cost chart", + render: () => ( + <> + + The monthly carrying-cost chart shows total inventory carrying cost + per calendar month, summed across every dwell step at the site. + +

+ It makes the seasonal shape of the carrying burden visible and is + recomputed live as the cost assumptions change. See{" "} + WACC{" "} + and{" "} + + storage cost + + . +

+ + ), + }, + { + id: "dwell-tab", + title: "Dwell time / cost tab", + render: () => ( + <> + + The dwell tab ranks every dwell step at the site by its inventory + carrying cost over the selected period. + +

+ Each row shows the observed dwell time and the period cost; sorting + surfaces the most expensive waits first. Rows open the step detail + for the full distribution and cost breakdown. +

+ + ), + }, + { + id: "planning-tab", + title: "Planning parameters tab", + render: () => ( + <> + + The planning tab ranks steps by how far observed timing deviates + from the planning parameter held for the step. + +

+ It surfaces where the plan and reality diverge most — both + steps running over plan and steps comfortably under it — as + candidates for planning recalibration. +

+ + ), + }, + { + id: "trend-tab", + title: "Trend tab", + render: () => ( + <> + + The Trend tab lists steps whose median lead time is moving up or + down versus the previous comparison period. + +

+ Use it as a directional signal beside the dwell and planning tabs: + worsening rows can point to emerging delays, while improving rows + can confirm that recent changes are reducing observed timing. +

+ + ), + }, + { + id: "supplier-tab", + title: "Supplier performance tab", + supplierFlagGated: true, + render: () => ( + <> + + The supplier tab is a leaderboard of vendors, pooling every delivery + a vendor made into the plant across all materials in scope. + +

+ Vendors are scored on on-time delivery against their promised dates + and on delivery delay. Both an expected delay across all deliveries + and the severity conditional on late deliveries are shown, so a + mostly-reliable vendor with occasional severe misses is not hidden + by an on-time majority. Vendors with very few measured deliveries + are held back to keep the rankings stable. +

+

+ Selecting a vendor opens a drill-down with that vendor's OTIF + trend and worst late deliveries. Procurement step details can also + show supplier performance for the selected material, while the site + tab pools deliveries across all materials in scope. +

+ + This view is only present when supplier performance is enabled. + + + ), + }, + { + id: "site-filters", + title: "Site filters & controls", + render: () => ( + <> + + Two controls are specific to the site view and sit alongside the + lower detail tables or shared analysis settings. + +
    +
  • + Category filter — shown on the Planning + parameters and Trend tabs to restrict those tables to chosen step + categories. It is hidden on the Dwell tab, and the Dwell category + is omitted from the Planning parameters filter. +
  • +
  • + Exclude low samples — hide steps with fewer + than 10 observations, so rankings are not dominated by noisy + single-event steps. +
  • +
+

+ All other controls are shared across views — see{" "} + + Settings & controls + + . +

+ + ), + }, + ], +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-detail.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-detail.tsx new file mode 100644 index 00000000000..c67ed702c67 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-detail.tsx @@ -0,0 +1,118 @@ +import { Lead, P, H4, Term, UL, LI, Note, CrossRef } from "../docs-primitives"; + +import type { DocEntry } from "../docs-types"; + +export const stepDetailDoc: DocEntry = { + id: "step-detail", + title: "Step detail panel", + render: () => ( + <> + + The step detail panel is the main place to investigate a single + value-chain step after selecting a product card, canvas node, site table + row or opportunity. + +

+ It keeps the step's method explanation close by through the + “About this step” button, but the panel itself is about + evidence: distributions, trends, records, status and related operational + dimensions. +

+ +

Dimensions

+
    +
  • + Timing is the default view. It shows the step's + duration distribution, monthly trend, planning comparison and source + records. +
  • +
  • + Receipt ratio appears on production steps when + receipt/yield data is available. It compares received quantity with + the order quantity. +
  • +
  • + Consumption appears when component consumption is + available. It shows aggregate variance and lets you inspect + component-level consumption against expectation. +
  • +
  • + Supplier appears on procurement steps when supplier + performance is enabled. It separates vendor execution against promised + dates from procurement lead time. +
  • +
+ +

Charts and statistics

+
    +
  • + Statistics list the named measures directly: min, mean, + median, P75, P85, P95, max and sample count. These values stay + explicit even when the global Measure setting changes the headline + value elsewhere. +
  • +
  • + Distribution shows the spread of observations for the + active time range and dimension. Use it to distinguish one-off tails + from broad shifts in the whole series. +
  • +
  • + Monthly trend shows how timing, cost, receipt ratio or + consumption has moved over time. Selecting a month filters the + evidence table to the records behind that point. +
  • +
  • + Planning comparison shows the planning parameter, the + difference from observed timing and the source note where the plan is + not the default planned-delivery-time field. +
  • +
+ +

Evidence and actions

+
    +
  • + Source records open from the table button in the header. + The table can be filtered by the active month and exported to CSV for + follow-up checks in another system. +
  • +
  • + Time range buttons filter the panel independently while + keeping it consistent with the same 3m / 6m / 12m windows used + elsewhere. +
  • +
  • + Outlier count appears in the header when the Exclude + outliers setting removes timing observations from the current step. + See{" "} + + Exclude outliers + + . +
  • +
  • + Brief opens a printable opportunity brief when the step + is part of a site opportunity. The brief turns the evidence into an + investigation narrative. +
  • +
  • + Status lets you record investigation progress, updates, + conclusions or rejections. Status history is tied to the + step/opportunity and reappears when the same target is opened again. +
  • +
+ +

Cost and supplier drill-down

+

+ Dwell steps with material cost data include a savings calculator that + estimates carrying-cost impact from reducing dwell days. Procurement + supplier views can drill from a vendor row into a vendor detail panel + with on-time trend and late-delivery examples. +

+ + Step detail evidence is still filtered by the selected product or site + context. A shared site step may show multiple products in the header; + use those links to jump to the product-specific view of the same step. + + + ), +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-dwell.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-dwell.tsx new file mode 100644 index 00000000000..d344e7eb62f --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-dwell.tsx @@ -0,0 +1,86 @@ +import { + Lead, + P, + H4, + Term, + SpanList, + SpanItem, + CrossRef, +} from "../docs-primitives"; + +import type { DocEntry } from "../docs-types"; + +export const dwellDoc: DocEntry = { + id: "dwell", + title: "Dwell", + render: () => ( + <> + + Dwell measures how long material waits in inventory between two events. + There are four dwell points across the value chain, each measuring a + different wait. + +

+ One observation per event. Dwell is measured at every + individual consumption or movement event, not as a single average per + batch. A batch drawn from stock across three production orders produces + three observations, each dated at its actual draw, so the timing + distribution and time filtering reflect real calendar activity. +

+ +

The four dwell spans

+ + + How long a purchased input waits in stock after receipt before it is + consumed into production. + + + How long an in-house intermediate waits after it is produced before + the next production stage consumes it. + + + How long finished product waits after QA release before it is issued + for shipment. + + + How long finished product sits at a distribution hub after arrival + before its first onward dispatch. + + + +

Carrying cost

+

+ Every dwell point carries an inventory carrying-cost view: the quantity + in stock multiplied by the days it is held, costed with a + cost-of-capital rate and a physical storage rate. The cost is built from + a month-by-month balance so material consumed early in a month is not + charged for the rest of it. Both rates are adjustable — see{" "} + WACC and{" "} + + storage cost + + . +

+ + ), +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-procurement.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-procurement.tsx new file mode 100644 index 00000000000..da5fdb8c62c --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-procurement.tsx @@ -0,0 +1,55 @@ +import { Lead, P, H4, Term, Note, CrossRef } from "../docs-primitives"; + +import type { DocEntry } from "../docs-types"; + +export const procurementDoc: DocEntry = { + id: "procurement", + title: "Procurement", + render: () => ( + <> + + Procurement measures how long a purchased input takes to arrive: the + elapsed time from purchase-order creation to the selected receipt + milestone, either first goods receipt or full receipt. + +

+ What it measures: purchase order creation to the active + procurement basis. First receipt captures when stock first lands; full + receipt captures when the order is complete. Every order contributes one + lead-time observation for the selected basis, so a material ordered many + times produces many observations. +

+

+ Time filtering: observations are anchored to the receipt + date for the active basis, so the 3m / 6m / 12m window selects receipts + that landed inside that period. +

+

Planning comparison

+

+ Procurement timing is compared against the planned delivery time held + for the material. On the process graph the step node is coloured by how + the headline value compares to that plan, and the site planning table + ranks materials by how far observed timing deviates from it. +

+

Supplier dimension

+

+ Where supplier performance is enabled, procurement steps expose an + additional view that isolates supplier execution: how + reliably the vendor delivers against the date they promised, reported as + on-time rate and OTIF (on-time in-full). Two delay figures are shown per + vendor: expected delay across all deliveries, and severity conditional + on the late deliveries only. +

+ + The headline procurement lead time and the supplier view answer + different questions. Lead time spans planner buffer plus supplier + execution; the supplier view strips out the buffer and looks only at + delivery against the promised date. See{" "} + + procurement basis + {" "} + for how first vs full receipt changes the headline. + + + ), +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-production.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-production.tsx new file mode 100644 index 00000000000..559d744ad16 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-production.tsx @@ -0,0 +1,47 @@ +import { Lead, P, H4, Term } from "../docs-primitives"; + +import type { DocEntry } from "../docs-types"; + +export const productionDoc: DocEntry = { + id: "production", + title: "Production", + render: () => ( + <> + + Production duration measures the per-batch cycle time: how long a batch + takes from the point production starts on it to the point it is + finished. + +

+ What it measures: production start to production finish, + per batch. The headline value is normalised to a typical batch size so + it reads as “days per typical batch” rather than being + skewed by unusually large or small campaigns. +

+

+ Planning comparison: production timing is compared against + the planned in-house production time for the material, and the + process-graph node is coloured accordingly. +

+ +

Receipt ratio

+

+ Production steps expose a receipt ratio view: the quantity + received against a production order versus the order quantity, expressed + as a percentage with 100% as the reference. It reflects order completion + and over-receipt rather than physical process yield. +

+ +

Input consumption variance

+

+ Production steps also expose an input consumption view: the + actual quantity of each input material consumed per order versus the + planned quantity, as a percentage. A positive variance is + over-consumption (more input used than planned); zero is the + expected-consumption reference. You can view the order-level weighted + aggregate or select a single component to see its own distribution and + trend. +

+ + ), +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-qa.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-qa.tsx new file mode 100644 index 00000000000..1c8b8534371 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-qa.tsx @@ -0,0 +1,31 @@ +import { Lead, P, Term } from "../docs-primitives"; + +import type { DocEntry } from "../docs-types"; + +export const qaDoc: DocEntry = { + id: "qa", + title: "QA hold / release", + render: () => ( + <> + + QA hold measures the time a finished batch waits between production + completion and QA release — the quality inspection and hold + period. + +

+ What it measures: production receipt (the batch is complete + and received into inventory) to QA release (the batch passes inspection + and is cleared for use). One observation per finished-good batch. +

+

+ Time filtering: observations are anchored to the + production-receipt date, so the selected window picks batches that + completed production inside that period. +

+

+ The wait that follows QA release — from release to dispatch + — is measured separately as post-QA dwell. +

+ + ), +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-transit.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-transit.tsx new file mode 100644 index 00000000000..98dde052ba9 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-content/step-transit.tsx @@ -0,0 +1,31 @@ +import { Lead, P, H4, Term } from "../docs-primitives"; + +import type { DocEntry } from "../docs-types"; + +export const transitDoc: DocEntry = { + id: "transit", + title: "Transit", + render: () => ( + <> + + Transit measures how long finished product takes to move from the + production plant to its next location on the way to the customer. + +

Plant to hub

+

+ What it measures: shipment out of the production plant to + the first receipt at a distribution hub. One observation per batch + arrival at the hub, anchored to the hub receipt date. +

+

Direct to customer

+

+ For product shipped to an external customer rather than an internal + destination, transit is measured from the goods issue shipment date to + the actual transport end date from transport documents. The customer + classification comes from the delivery's ship-to account, not from + the absence of a known hub receipt. Batches without an actual transport + end date are not included in this step. +

+ + ), +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-context.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-context.tsx new file mode 100644 index 00000000000..842c42d3203 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-context.tsx @@ -0,0 +1,25 @@ +import { useCallback, useMemo, useState, type ReactNode } from "react"; + +import { DocsModal } from "./docs-modal"; +import { DocsContext } from "./use-docs"; + +import type { DocSectionId, DocTarget } from "./docs-types"; + +export const DocsProvider = ({ children }: { children: ReactNode }) => { + const [target, setTarget] = useState(null); + + const openDocs = useCallback((section: DocSectionId, sub?: string) => { + setTarget({ section, sub }); + }, []); + + const value = useMemo(() => ({ openDocs }), [openDocs]); + + return ( + + {children} + {target && ( + setTarget(null)} /> + )} + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-modal.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-modal.tsx new file mode 100644 index 00000000000..aa0fec87328 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-modal.tsx @@ -0,0 +1,367 @@ +import { Portal } from "@ark-ui/react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + +import { Button, usePortalContainerRef } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { useSupplierPerformanceEnabled } from "../feature-flags"; +import { DOC_SECTIONS } from "./docs-content"; +import { DocEntryBlock, DocsNavProvider } from "./docs-primitives"; + +import type { + DocEntry, + DocSectionDef, + DocSectionId, + DocTarget, +} from "./docs-types"; + +const backdrop = css({ + position: "fixed", + inset: "0", + zIndex: "[1000]", + bg: "neutral.a80", + display: "flex", + alignItems: "center", + justifyContent: "center", + p: "4", +}); +const panel = css({ + display: "flex", + flexDirection: "column", + w: "[min(1040px,100%)]", + h: "[min(82vh,760px)]", + bg: "bgSolid.min", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "lg", + boxShadow: "2xl", + overflow: "hidden", +}); +const headerBar = css({ + display: "flex", + alignItems: "center", + justifyContent: "space-between", + gap: "3", + px: "5", + py: "3", + borderBottomWidth: "1px", + borderBottomStyle: "solid", + borderColor: "bd.subtle", + flexShrink: "0", +}); +const headerTitle = css({ + fontFamily: "display", + textStyle: "lg", + fontWeight: "medium", + color: "fg.heading", +}); +const bodyRow = css({ display: "flex", flex: "1", minH: "0" }); +const sidebar = css({ + w: "[248px]", + flexShrink: "0", + borderRightWidth: "1px", + borderRightStyle: "solid", + borderColor: "bd.subtle", + overflowY: "auto", + py: "3", + // Subtle top-down gradient (white -> faint cool tint) reads less flat than a solid grey panel. + bg: "[linear-gradient(180deg,#ffffff_0%,#f4f6fa_100%)]", + "@media (max-width: 640px)": { display: "none" }, +}); +const navSection = css({ "&:not(:first-child)": { mt: "2" } }); +const navSectionButton = css({ + display: "block", + w: "full", + textAlign: "left", + px: "4", + py: "1.5", + textStyle: "sm", + fontWeight: "semibold", + color: "fg.heading", + cursor: "pointer", + bg: "[transparent]", + border: "none", + _hover: { color: "fg.muted" }, +}); +const navSectionButtonActive = css({ color: "fg.heading" }); +const navEntry = css({ + display: "block", + w: "full", + textAlign: "left", + pl: "6", + pr: "4", + py: "1", + textStyle: "sm", + color: "fg.subtle", + cursor: "pointer", + bg: "[transparent]", + border: "none", + borderLeftWidth: "2px", + borderLeftStyle: "solid", + borderLeftColor: "[transparent]", + _hover: { color: "fg.muted" }, +}); +const navEntryActive = css({ + color: "fg.heading", + fontWeight: "medium", + borderLeftColor: "fg.heading", +}); +const content = css({ + flex: "1", + minW: "0", + overflowY: "auto", + px: "6", + py: "5", +}); +const sectionHeading = css({ + fontFamily: "display", + textStyle: "2xl", + fontWeight: "medium", + color: "fg.heading", + mb: "4", +}); + +function visibleEntries( + section: DocSectionDef, + supplierEnabled: boolean, +): DocEntry[] { + return section.entries.filter( + (event) => !event.supplierFlagGated || supplierEnabled, + ); +} + +/** Resolve which entry in a section owns a given anchor sub-id. */ +function entryIdForSub( + section: DocSectionDef, + sub: string | undefined, +): string | undefined { + if (!sub) { + return undefined; + } + const match = section.entries.find( + (event) => event.id === sub || sub.startsWith(`${event.id}-`), + ); + return match?.id; +} + +export const DocsModal = ({ + initialTarget, + onClose, +}: { + initialTarget: DocTarget; + onClose: () => void; +}) => { + const portalRef = usePortalContainerRef(); + const supplierEnabled = useSupplierPerformanceEnabled(); + const contentRef = useRef(null); + + const sections = useMemo( + () => + DOC_SECTIONS.map((step) => ({ + section: step, + entries: visibleEntries(step, supplierEnabled), + })), + [supplierEnabled], + ); + + const [activeSection, setActiveSection] = useState( + initialTarget.section, + ); + const [activeEntryId, setActiveEntryId] = useState(() => { + const step = DOC_SECTIONS.find( + (xValue) => xValue.id === initialTarget.section, + ); + return step ? entryIdForSub(step, initialTarget.sub) : undefined; + }); + // The scroll target carries a nonce so re-selecting the same anchor (e.g. + // clicking the same sidebar entry twice) still re-triggers the scroll effect. + const [scrollTarget, setScrollTarget] = useState<{ + sub?: string; + nonce: number; + }>({ + sub: initialTarget.sub, + nonce: 0, + }); + + const navigate = useCallback((target: DocTarget) => { + setActiveSection(target.section); + const step = DOC_SECTIONS.find((xValue) => xValue.id === target.section); + setActiveEntryId(step ? entryIdForSub(step, target.sub) : undefined); + setScrollTarget((prev) => ({ sub: target.sub, nonce: prev.nonce + 1 })); + }, []); + + // Scroll to the requested anchor after the active section has rendered. Keyed + // off `scrollTarget` only: its nonce changes on every navigation, so this also + // fires when the section switches (navigation always updates both at once). + useEffect(() => { + const container = contentRef.current; + if (!container) { + return; + } + const { sub } = scrollTarget; + if (!sub) { + container.scrollTo({ top: 0 }); + return; + } + const id = requestAnimationFrame(() => { + const el = container.querySelector(`[id="${sub}"]`); + if (el) { + el.scrollIntoView({ block: "start", behavior: "smooth" }); + } else { + container.scrollTo({ top: 0 }); + } + }); + return () => cancelAnimationFrame(id); + }, [scrollTarget]); + + // Scroll-spy: highlight the entry occupying the largest visible area in the + // modal viewport. This is more reliable than "heading crossed the top", + // because short final entries often cannot physically scroll to the top. + useEffect(() => { + const container = contentRef.current; + if (!container) { + return; + } + const entryIds = ( + sections.find((step) => step.section.id === activeSection)?.entries ?? [] + ).map((event) => event.id); + if (entryIds.length === 0) { + return; + } + let raf = 0; + const update = () => { + cancelAnimationFrame(raf); + raf = requestAnimationFrame(() => { + const containerRect = container.getBoundingClientRect(); + let current = entryIds[0]; + let bestVisible = -1; + + for (const id of entryIds) { + const el = container.querySelector(`[id="${id}"]`); + if (!el) { + continue; + } + const rect = el.getBoundingClientRect(); + const visibleTop = Math.max(rect.top, containerRect.top); + const visibleBottom = Math.min(rect.bottom, containerRect.bottom); + const visible = Math.max(0, visibleBottom - visibleTop); + if (visible > bestVisible) { + bestVisible = visible; + current = id; + } + } + + setActiveEntryId((prev) => (prev === current ? prev : current)); + }); + }; + container.addEventListener("scroll", update, { passive: true }); + update(); + return () => { + container.removeEventListener("scroll", update); + cancelAnimationFrame(raf); + }; + }, [sections, activeSection]); + + useEffect(() => { + const onKey = (event: KeyboardEvent) => { + if (event.key === "Escape") { + onClose(); + } + }; + document.addEventListener("keydown", onKey); + return () => document.removeEventListener("keydown", onKey); + }, [onClose]); + + const active = + sections.find((step) => step.section.id === activeSection) ?? sections[0]; + if (!active) { + return null; + } + + return ( + + {/* biome-ignore lint/a11y/useKeyWithClickEvents: The backdrop is pointer-only; Escape is handled globally above. */} +
{ + if (event.target === event.currentTarget) { + onClose(); + } + }} + > + {/* biome-ignore lint/a11y/useSemanticElements: Native positioning conflicts with the portal/backdrop layout. */} +
+
+

Documentation

+
+
+ +
+ +

{active.section.title}

+ {active.entries.map((entry) => ( + + {entry.render()} + + ))} +
+
+
+
+
+
+ ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-primitives.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-primitives.tsx new file mode 100644 index 00000000000..3a6b0d4066e --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-primitives.tsx @@ -0,0 +1,296 @@ +import { createContext, useContext, type ReactNode } from "react"; + +import { css } from "@hashintel/ds-helpers/css"; + +import type { DocTarget } from "./docs-types"; + +/** + * In-modal navigation. The modal provides a `navigate` callback so content can + * render cross-reference links that jump to another section/entry (e.g. an + * overview pointing at "Settings & controls"). + */ +const DocsNavContext = createContext<(target: DocTarget) => void>(() => {}); + +export const DocsNavProvider = ({ + navigate, + children, +}: { + navigate: (target: DocTarget) => void; + children: ReactNode; +}) => { + return ( + + {children} + + ); +}; + +const entryBlock = css({ + scrollMarginTop: "4", + "&:not(:first-child)": { + mt: "8", + pt: "8", + borderTopWidth: "1px", + borderColor: "bd.subtle", + }, +}); +const entryTitle = css({ + fontFamily: "display", + textStyle: "base", + fontWeight: "medium", + color: "fg.heading", + mb: "3", +}); +// Anchors wrap block-level setting rows; space consecutive ones apart (the +// inner SettingRow's own `:not(:first-child)` margin can't fire when it's the +// sole child of each Anchor). +const anchor = css({ + scrollMarginTop: "4", + "&:not(:first-child)": { mt: "3" }, +}); + +/** A navigable docs entry: an anchored heading plus its body. */ +export const DocEntryBlock = ({ + id, + title, + children, +}: { + id: string; + title: string; + children: ReactNode; +}) => { + return ( +
+

{title}

+ {children} +
+ ); +}; + +/** An in-content anchor target (e.g. a dwell span) that the modal can scroll to. */ +export const Anchor = ({ + id, + children, +}: { + id: string; + children: ReactNode; +}) => { + return ( +
+ {children} +
+ ); +}; + +const lead = css({ + textStyle: "base", + color: "fg.muted", + lineHeight: "relaxed", + mb: "3", +}); +export const Lead = ({ children }: { children: ReactNode }) => { + return

{children}

; +}; + +const para = css({ + textStyle: "sm", + color: "fg.subtle", + lineHeight: "relaxed", + "&:not(:first-child)": { mt: "2.5" }, +}); +const Paragraph = ({ children }: { children: ReactNode }) => { + return

{children}

; +}; +export { Paragraph as P }; + +const h4 = css({ + textStyle: "base", + fontWeight: "medium", + color: "fg.heading", + mt: "5", + mb: "2", +}); +export const H4 = ({ children }: { children: ReactNode }) => { + return

{children}

; +}; + +const ul = css({ + mt: "2.5", + display: "flex", + flexDirection: "column", + gap: "2", + pl: "1", +}); +export const UL = ({ children }: { children: ReactNode }) => { + return
    {children}
; +}; + +const li = css({ + textStyle: "sm", + color: "fg.subtle", + lineHeight: "relaxed", + pl: "4", + position: "relative", + _before: { + content: '"\\2022"', + position: "absolute", + left: "0", + color: "fg.muted", + fontWeight: "semibold", + }, +}); +export const LI = ({ children }: { children: ReactNode }) => { + return
  • {children}
  • ; +}; + +const term = css({ fontWeight: "medium", color: "fg.heading" }); +export const Term = ({ children }: { children: ReactNode }) => { + return {children}; +}; + +const note = css({ + mt: "3", + borderLeftWidth: "2px", + borderColor: "bd.subtle", + pl: "3", + py: "0.5", + textStyle: "sm", + color: "fg.subtle", + lineHeight: "relaxed", +}); +export const Note = ({ children }: { children: ReactNode }) => { + return
    {children}
    ; +}; + +/** A span definition row: "Start -> End" with an explanation. Used for dwell variants. */ +const spanList = css({ + mt: "3", + display: "flex", + flexDirection: "column", + gap: "3", +}); +export const SpanList = ({ children }: { children: ReactNode }) => { + return
    {children}
    ; +}; + +const spanItem = css({ + borderWidth: "1px", + borderColor: "bd.subtle", + borderRadius: "md", + p: "3", + scrollMarginTop: "4", +}); +const spanHead = css({ + display: "flex", + alignItems: "center", + gap: "1.5", + flexWrap: "wrap", + mb: "1.5", +}); +const spanName = css({ + textStyle: "sm", + fontWeight: "semibold", + color: "fg.heading", +}); +const spanArrow = css({ + display: "inline-flex", + alignItems: "center", + gap: "1.5", + textStyle: "xs", + fontWeight: "medium", + color: "fg.muted", + bg: "bg.subtle", + borderRadius: "sm", + px: "1.5", + py: "0.5", +}); +const spanBody = css({ + textStyle: "sm", + color: "fg.subtle", + lineHeight: "relaxed", +}); +export const SpanItem = ({ + id, + name, + from, + to, + children, +}: { + id?: string; + name: string; + from: string; + to: string; + children: ReactNode; +}) => { + return ( +
    +
    + {name} + + {from} {"\u2192"} {to} + +
    +

    {children}

    +
    + ); +}; + +/** A labelled control/setting definition row. */ +const settingRow = css({ + display: "flex", + flexDirection: "column", + gap: "0.5", + "&:not(:first-child)": { mt: "3" }, +}); +const settingName = css({ + textStyle: "sm", + fontWeight: "semibold", + color: "fg.heading", +}); +const settingBody = css({ + textStyle: "sm", + color: "fg.subtle", + lineHeight: "relaxed", +}); +export const SettingRow = ({ + name, + children, +}: { + name: string; + children: ReactNode; +}) => { + return ( +
    + {name} + {children} +
    + ); +}; + +const crossRef = css({ + color: "fg.heading", + fontWeight: "medium", + textDecoration: "underline", + textUnderlineOffset: "[2px]", + cursor: "pointer", + bg: "[transparent]", + border: "none", + p: "0", + font: "inherit", + _hover: { color: "fg.muted" }, +}); +/** A link inside docs copy that jumps to another section/entry of the modal. */ +export const CrossRef = ({ + to, + children, +}: { + to: DocTarget; + children: ReactNode; +}) => { + const navigate = useContext(DocsNavContext); + return ( + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-types.ts b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-types.ts new file mode 100644 index 00000000000..c5a964b62c3 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/docs-types.ts @@ -0,0 +1,40 @@ +import type { ReactNode } from "react"; + +/** Top-level docs sections shown in the modal sidebar. */ +export type DocSectionId = + | "site-overview" + | "product-overview" + | "steps" + | "opportunity-brief" + | "settings"; + +/** + * A navigable docs entry. Each entry renders a self-contained block of copy and + * is addressable by `id` so the modal can deep-link / scroll to it (e.g. from a + * step slideover or a cross-reference link). + */ +export interface DocEntry { + /** Stable id, unique across all sections; doubles as the scroll-target DOM id. */ + id: string; + /** Sidebar label. */ + title: string; + /** + * When true the entry is only shown if the Supplier Performance feature flag + * is enabled (see `useSupplierPerformanceEnabled`). + */ + supplierFlagGated?: boolean; + render: () => ReactNode; +} + +export interface DocSectionDef { + id: DocSectionId; + title: string; + entries: DocEntry[]; +} + +/** A navigation target inside the modal: a section, optionally scrolled to an entry. */ +export interface DocTarget { + section: DocSectionId; + /** Entry id (or any in-content anchor id) to scroll to. */ + sub?: string; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/docs/use-docs.ts b/apps/hash-frontend/src/pages/supply-chain/shared/docs/use-docs.ts new file mode 100644 index 00000000000..aaa24c0c2a9 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/docs/use-docs.ts @@ -0,0 +1,14 @@ +import { createContext, useContext } from "react"; + +import type { DocSectionId } from "./docs-types"; + +export interface DocsCtx { + /** Open the docs modal at a section, optionally scrolled to an entry/anchor. */ + openDocs: (section: DocSectionId, sub?: string) => void; +} + +export const DocsContext = createContext({ openDocs: () => {} }); + +export function useDocs() { + return useContext(DocsContext); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/export-utils.ts b/apps/hash-frontend/src/pages/supply-chain/shared/export-utils.ts new file mode 100644 index 00000000000..6894c4c2460 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/export-utils.ts @@ -0,0 +1,45 @@ +import type { DetailColumn } from "./types"; + +export function buildCsvContent( + columns: DetailColumn[], + rows: Record[], +): string { + const headers = columns.map((col) => { + if (col.source_table && col.source_field) { + return `"${col.label} (${col.source_table}.${col.source_field})"`; + } + return `"${col.label}"`; + }); + + const csvRows = rows.map((row) => + columns + .map((col) => { + const val = row[col.key]; + if (val == null) { + return ""; + } + if ( + typeof val === "string" && + (val.includes(",") || val.includes('"')) + ) { + return `"${val.replace(/"/g, '""')}"`; + } + return String(val); + }) + .join(","), + ); + + return [headers.join(","), ...csvRows].join("\n"); +} + +export function downloadCsv(content: string, filename: string) { + const blob = new Blob([content], { type: "text/csv;charset=utf-8;" }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = filename; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + URL.revokeObjectURL(url); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/feature-flags.ts b/apps/hash-frontend/src/pages/supply-chain/shared/feature-flags.ts new file mode 100644 index 00000000000..c5871509a63 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/feature-flags.ts @@ -0,0 +1,43 @@ +import { useSearchParams } from "./use-search-params"; + +/** + * Feature flags for the supply-chain views. + * + * A flag resolves from a query param so experimental views can be enabled or + * hidden per URL without changing the app-wide supply-chain feature flag. + */ + +function parseBoolish(value: string | null | undefined): boolean | null { + if (value == null) { + return null; + } + switch (value.trim().toLowerCase()) { + case "1": + case "true": + case "on": + case "yes": + return true; + case "0": + case "false": + case "off": + case "no": + return false; + default: + return null; + } +} + +/** + * Supplier Performance is an experimental view (dashboard card, tab + table, + * and vendor drill-down). It is hidden by default; enable it with + * `?supplierPerformance=1`. + */ +export function useSupplierPerformanceEnabled(): boolean { + const [searchParams] = useSearchParams(); + const fromQuery = parseBoolish(searchParams.get("supplierPerformance")); + if (fromQuery != null) { + return fromQuery; + } + + return false; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/header-actions.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/header-actions.tsx new file mode 100644 index 00000000000..d9ed3933be6 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/header-actions.tsx @@ -0,0 +1,287 @@ +import { NumberInput, Icon } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { DocsIconButton } from "./action-buttons"; +import { useCostParams, useOutlierSetting } from "./cost"; +import { useDocs } from "./docs/use-docs"; +import { + BASE_MEASURES, + MEASURE_LABELS, + useBaseMeasure, + type BaseMeasure, +} from "./measure-context"; +import { + PROCUREMENT_BASES, + PROCUREMENT_BASIS_LABELS, + useProcurementBasis, + type ProcurementBasis, +} from "./procurement-basis-context"; +import { SegmentedControl } from "./segmented-control"; +import { trackSupplyChainInteraction } from "./telemetry"; +import { TIME_RANGE_OPTIONS } from "./time-range"; +import { useTimeRange } from "./time-range-context"; + +import type { ReactNode } from "react"; + +const actionRow = css({ + display: "flex", + alignItems: "center", + gap: "1.5", + minH: "[30px]", +}); +const iconButton = css({ + display: "inline-flex", + alignItems: "center", + justifyContent: "center", + h: "7", + w: "7", + borderRadius: "md", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bgSolid.min", + color: "fg.subtle", + cursor: "pointer", + transition: "colors", + _hover: { color: "fg.heading", bg: "bg.subtle" }, +}); +const iconButtonActive = css({ color: "fg.heading", bg: "bg.subtle" }); +const settingsWrap = css({ + mt: "3", + borderTopWidth: "1px", + borderColor: "bd.subtle", + pt: "3", + display: "flex", + alignItems: "center", + justifyContent: "flex-end", + gap: "4", + "@media (max-width: 767px)": { + position: "fixed", + top: "0", + right: "0", + bottom: "0", + zIndex: "modal", + w: "[min(360px,92vw)]", + alignItems: "flex-start", + justifyContent: "flex-start", + flexDirection: "column", + bg: "bgSolid.min", + borderLeftWidth: "1px", + borderTopWidth: "0", + boxShadow: "2xl", + p: "4", + mt: "0", + overflowY: "auto", + }, +}); +const settingsTitleRow = css({ + textStyle: "base", + fontWeight: "semibold", + color: "fg.heading", + display: "none", + "@media (max-width: 767px)": { + display: "flex", + alignItems: "center", + justifyContent: "space-between", + gap: "3", + w: "full", + }, +}); +const sharedFields = css({ + display: "flex", + flexWrap: "wrap", + alignItems: "center", + justifyContent: "flex-end", + gap: "3", +}); +const fieldLabel = css({ + display: "flex", + alignItems: "center", + gap: "1.5", + textStyle: "xs", + color: "fg.subtle", + whiteSpace: "nowrap", +}); +const measureSelect = css({ + textStyle: "xs", + color: "fg.heading", + fontWeight: "medium", + bg: "bgSolid.min", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "sm", + px: "1.5", + py: "0.5", + cursor: "pointer", +}); +const extraFields = css({ + display: "flex", + flexWrap: "wrap", + alignItems: "center", + justifyContent: "flex-end", + gap: "3", +}); + +export const HeaderActionButtons = ({ + settingsOpen, + onSettingsToggle, + docContext, +}: { + settingsOpen: boolean; + onSettingsToggle: () => void; + /** Which docs section the help button opens, based on the host view. */ docContext: + | "site" + | "product"; +}) => { + const { openDocs } = useDocs(); + + return ( +
    + + { + trackSupplyChainInteraction({ + interaction: "docs_opened", + source: docContext === "site" ? "site_overview" : "product_page", + }); + openDocs( + docContext === "site" ? "site-overview" : "product-overview", + ); + }} + /> +
    + ); +}; + +export const AnalysisSettingsPanel = ({ + children, + onClose, + className, +}: { + children?: ReactNode; + onClose?: () => void; + className?: string; +}) => { + const { currency, waccRate, setWaccRate, storageCost, setStorageCost } = + useCostParams(); + const { excludeOutliers, setExcludeOutliers } = useOutlierSetting(); + const { measure, setMeasure } = useBaseMeasure(); + const { basis, setBasis } = useProcurementBasis(); + const { timeRange, setTimeRange } = useTimeRange(); + + return ( +
    +
    +

    Analysis settings

    + {onClose && ( + + )} +
    +
    + + WACC + { + if (value != null && value > 0 && value <= 50) { + setWaccRate(value / 100); + } + }} + aria-label="WACC percent" + /> + % + + + Storage + { + if (value != null && value > 0 && value <= 10) { + setStorageCost(value); + } + }} + aria-label="Storage cost per tonne per day" + /> + {currency}/t/d + + + + + + +
    + {children != null &&
    {children}
    } +
    + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/load-state.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/load-state.tsx new file mode 100644 index 00000000000..f9222cbda58 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/load-state.tsx @@ -0,0 +1,45 @@ +import { LoadingSpinner } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +const center = css({ + display: "flex", + alignItems: "center", + justifyContent: "center", +}); +const loadingRow = css({ + display: "flex", + alignItems: "center", + gap: "2", + color: "fg.subtle", +}); +const loadingText = css({ textStyle: "sm", color: "fg.subtle" }); +const errorText = css({ textStyle: "sm", color: "status.error.fg.body" }); + +/** Centered, muted "loading…" message with a ds spinner. Size the area via `className` (e.g. `h-32`). */ +export const LoadingState = ({ + message, + className, +}: { + message: string; + className?: string; +}) => { + return ( +
    +
    + +

    {message}

    +
    +
    + ); +}; + +/** Inline error message. Pad/position via `className` (e.g. `px-6 py-4`). */ +export const ErrorState = ({ + message, + className, +}: { + message: string; + className?: string; +}) => { + return

    {message}

    ; +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/measure-context.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/measure-context.test.ts new file mode 100644 index 00000000000..5e95728753d --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/measure-context.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "vitest"; + +import { selectStat, statOf } from "./measure-context"; +import { computeStats } from "./stats"; + +import type { StepStats } from "./types"; + +describe("selectStat", () => { + const stats: StepStats = { + n: 4, + mean: 12, + median: 11, + std: 1, + min: 10, + max: 14, + p25: 10.5, + p75: 12.5, + p85: 13, + p95: 13.8, + }; + + it("reads the requested measure off a stats block", () => { + expect(selectStat(stats, "median")).toBe(11); + expect(selectStat(stats, "mean")).toBe(12); + expect(selectStat(stats, "p75")).toBe(12.5); + expect(selectStat(stats, "p95")).toBe(13.8); + }); + + it("returns null for missing stats", () => { + expect(selectStat(null, "median")).toBeNull(); + expect(selectStat(undefined, "p95")).toBeNull(); + }); +}); + +describe("statOf", () => { + it("computes mean/median/p75/p95 from a raw value list", () => { + const values = [10, 20, 30]; + expect(statOf(values, "mean")).toBeCloseTo(20, 6); + expect(statOf(values, "median")).toBeCloseTo(20, 6); + expect(statOf(values, "p75")).toBeCloseTo(25, 6); + expect(statOf(values, "p95")).toBeCloseTo(29, 6); + }); + + it("matches computeStats (modulo rounding) for the median", () => { + const values = [4, 8, 15, 16, 23, 42]; + expect(statOf(values, "median")).toBeCloseTo( + computeStats(values).median ?? 0, + 5, + ); + }); + + it("returns null on an empty list", () => { + expect(statOf([], "median")).toBeNull(); + expect(statOf([], "p95")).toBeNull(); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/measure-context.ts b/apps/hash-frontend/src/pages/supply-chain/shared/measure-context.ts new file mode 100644 index 00000000000..505692f5b15 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/measure-context.ts @@ -0,0 +1,88 @@ +import { createContext, useContext } from "react"; + +import { percentileOf } from "./stats"; + +import type { StepStats } from "./types"; + +/** + * The base statistic used as the "headline" timing measure across the app: + * product step-card headline + over/under badge, site planning deviation / + * bad-param count / planning + dwell "Observed" columns, and timing trends. + * + * Maps 1:1 to `StepStats` keys. Defaults to `median`. Does NOT affect the mini + * box-plot (shows mean+median) or the named stat tables in the slideover, which + * always show explicit stats. + */ +export type BaseMeasure = "median" | "mean" | "p75" | "p95"; + +export const BASE_MEASURES: readonly BaseMeasure[] = [ + "median", + "mean", + "p75", + "p95", +]; + +/** Short label for the toolbar control + tooltips. */ +export const MEASURE_LABELS: Record = { + median: "Median", + mean: "Mean", + p75: "P75", + p95: "P95", +}; + +interface MeasureCtx { + measure: BaseMeasure; + setMeasure: (measure: BaseMeasure) => void; +} + +export const MeasureContext = createContext({ + measure: "median", + setMeasure: () => {}, +}); + +export function useBaseMeasure() { + return useContext(MeasureContext); +} + +/** The percentile (0..100) for a percentile-style measure, else null. */ +function measurePercentile(measure: BaseMeasure): number | null { + switch (measure) { + case "p75": + return 75; + case "p95": + return 95; + default: + return null; + } +} + +/** Read the selected measure off a precomputed `StepStats` block. */ +export function selectStat( + stats: StepStats | null | undefined, + measure: BaseMeasure, +): number | null { + if (!stats) { + return null; + } + return stats[measure] ?? null; +} + +/** + * Compute the selected measure directly from a raw value list. Mirrors the + * rounding/interpolation in `computeStats` so the result matches the + * `StepStats` field for the same values. Returns null for an empty list. + */ +export function statOf(values: number[], measure: BaseMeasure): number | null { + if (values.length === 0) { + return null; + } + if (measure === "mean") { + return values.reduce((left, right) => left + right, 0) / values.length; + } + const sorted = [...values].sort((left, right) => left - right); + const product = measurePercentile(measure); + if (product != null) { + return percentileOf(sorted, product); + } + return percentileOf(sorted, 50); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/node-badges.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/node-badges.test.ts new file mode 100644 index 00000000000..f77d859aad5 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/node-badges.test.ts @@ -0,0 +1,74 @@ +import { describe, expect, it } from "vitest"; + +import { makeNode, obs } from "./observation-fixtures"; +import { applyOutlierSelectionToNode } from "./outlier-selection"; +import { windowGraphNodeToRange } from "./range-filter"; + +import type { NodeYieldSeries, NodeConsumptionSeries } from "./types"; + +const yieldSeries: NodeYieldSeries = { + reference: 95, + observations: [ + obs("2026-01", 90), + obs("2026-02", 92), + obs("2026-03", 95), + obs("2026-04", 93), + ], +}; + +const consumptionSeries: NodeConsumptionSeries = { + n_components: 2, + observations: [ + { ...obs("2026-01", 4), actual_qty: 104, expected_qty: 100 }, + { ...obs("2026-02", 6), actual_qty: 106, expected_qty: 100 }, + { ...obs("2026-03", 2), actual_qty: 102, expected_qty: 100 }, + ], +}; + +describe("node R:/C: badge recompute from shipped series", () => { + it("recomputes yield_summary from the windowed series", () => { + const node = makeNode({ type: "production", yield_series: yieldSeries }); + const windowed = windowGraphNodeToRange(node, "12m"); + expect(windowed.yield_summary?.median).toBeCloseTo(92.5, 6); + expect(windowed.yield_summary?.reference).toBe(95); + expect(windowed.yield_summary?.n).toBe(4); + }); + + it("recomputes consumption_summary (incl. weighted variance) from the windowed series", () => { + const node = makeNode({ + type: "production", + consumption_series: consumptionSeries, + }); + const windowed = windowGraphNodeToRange(node, "12m"); + expect(windowed.consumption_summary?.median_variance).toBeCloseTo(4, 6); + expect(windowed.consumption_summary?.n_components).toBe(2); + // weighted = (sum actual - sum expected)/sum expected = (312-300)/300 = 4% + expect(windowed.consumption_summary?.weighted_variance).toBeCloseTo(4, 6); + }); + + it("leaves the shipped summary untouched when no series is present", () => { + const node = makeNode({ + type: "production", + yield_summary: { median: 88, mean: 88, reference: 95, n: 3 }, + }); + const windowed = windowGraphNodeToRange(node, "12m"); + expect(windowed.yield_summary?.median).toBe(88); + }); + + it("drops outliers from the yield series under the outlier rule", () => { + const withOutlier: NodeYieldSeries = { + reference: 95, + observations: [...yieldSeries.observations, obs("2026-05", 5)], + }; + const node = makeNode({ type: "production", yield_series: withOutlier }); + const selected = applyOutlierSelectionToNode(node, true); + // The 5% point is far below the others' IQR fence and is dropped. + expect( + selected.yield_series?.observations.some( + (observation) => observation.value === 5, + ), + ).toBe(false); + const windowed = windowGraphNodeToRange(selected, "12m"); + expect(windowed.yield_summary?.n).toBe(4); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/normalize-contract.ts b/apps/hash-frontend/src/pages/supply-chain/shared/normalize-contract.ts new file mode 100644 index 00000000000..4305182ea88 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/normalize-contract.ts @@ -0,0 +1,323 @@ +import { + deriveProcurementTimingFromRows, + isProcurementNodeObservation, + procurementNodeObservationsForBasis, +} from "./procurement-observations"; +import { computeStats, percentileOf, round } from "./stats"; + +import type { + GraphData, + GraphNode, + StepDetail, + Observation, + StepStats, + MonthlyBucket, + ProcurementNodeObservation, +} from "./types"; + +/** + * Load-time contract normalization. + * + * The wire ships a slim payload: a single canonical observation series per + * family, with the `stats` block and per-month timing left off (a fixed + * mean/median/p95 can't respect the client's window/outlier toggles, which + * recompute on every change). These helpers refill `stats`/`monthly` from + * `observations` on load so downstream read sites can treat them as always + * present. + */ + +function hasStats(step: StepStats | null | undefined): step is StepStats { + return !!step && typeof step.n === "number"; +} + +function statsFromObservations( + obs: Observation[] | undefined | null, +): StepStats { + return computeStats((obs ?? []).map((observation) => observation.value)); +} + +function pctExceeding( + obs: Observation[] | undefined | null, + threshold: number | null | undefined, +): number | null { + if (threshold == null) { + return null; + } + const values = (obs ?? []).map((observation) => observation.value); + if (values.length === 0) { + return null; + } + return round( + (100 * values.filter((value) => value > threshold).length) / values.length, + ); +} + +/** A series block shaped like `yield_data` / a consumption component / aggregate. */ +interface SeriesLike { + observations?: Observation[]; + stats?: StepStats; +} + +function ensureSeriesStats( + series: T | null | undefined, +): T | null | undefined { + if (!series || hasStats(series.stats)) { + return series; + } + return { ...series, stats: statsFromObservations(series.observations) }; +} + +/** + * Rebuild a secondary {@link TimingSeries}' `monthly`/`stats` from its + * `observations` when absent. The wire ships these series observations-only; + * precomputed monthly/stats can't respect the window/outlier toggles, so the + * client always derives them. No-op when both are already present. + */ + +/** Group an observation set into per-month timing buckets (records-derive). */ +function buildMonthlyFromObservations(obs: Observation[]): MonthlyBucket[] { + const byMonth = new Map(); + for (const observation of obs) { + const month = observation.date.slice(0, 7); + const arr = byMonth.get(month); + if (arr) { + arr.push(observation.value); + } else { + byMonth.set(month, [observation.value]); + } + } + return [...byMonth.keys()].sort().map((month) => { + const sorted = [...(byMonth.get(month) ?? [])].sort( + (left, right) => left - right, + ); + return { + month, + mean: round( + sorted.reduce((left, right) => left + right, 0) / sorted.length, + ), + median: round(percentileOf(sorted, 50)), + n: sorted.length, + }; + }); +} + +/** + * Single-source records derive. When a step ships only the canonical + * `detail_rows` (+ `value_col`/`ref_date_col`) and no precomputed timing series, + * rehydrate observations/durations/monthly/stats from the rows. A strict no-op + * whenever `observations` are already present. + */ function ensureTimingSeriesStats< + T extends { + observations?: Observation[]; + monthly?: MonthlyBucket[]; + stats?: StepStats | null; + }, +>(ts: T | null | undefined): T | null | undefined { + if (!ts) { + return ts; + } + if (ts.monthly && ts.monthly.length > 0 && hasStats(ts.stats)) { + return ts; + } + const obs = ts.observations ?? []; + return { + ...ts, + monthly: buildMonthlyFromObservations(obs), + stats: computeStats(obs.map((observation) => observation.value)), + }; +} +function normalizeProcurementNode(node: GraphNode): GraphNode { + if (node.type !== "procurement") { + return node; + } + const raw = + node.procurement_observations ?? + ((node.observations as unknown[] | undefined)?.every( + isProcurementNodeObservation, + ) + ? (node.observations as unknown as ProcurementNodeObservation[]) + : undefined); + if (!raw || raw.length === 0) { + return node; + } + const observations = procurementNodeObservationsForBasis(raw, "first"); + return { + ...node, + procurement_observations: raw, + observations, + monthly: buildMonthlyFromObservations(observations), + }; +} +/** Fill a graph node's `stats` from its observations when absent. */ export function ensureNodeStats( + node: GraphNode, +): GraphNode { + const normalized = normalizeProcurementNode(node); + const observations = normalized.observations ?? []; + const withMonthly = + normalized.monthly && normalized.monthly.length > 0 + ? normalized + : { ...normalized, monthly: buildMonthlyFromObservations(observations) }; + const base = hasStats(withMonthly.stats) + ? withMonthly + : { ...withMonthly, stats: statsFromObservations(observations) }; + return { + ...base, + pct_exceeding_plan: pctExceeding(base.observations, base.plan), + }; +} +/** Normalize every node in a product graph (+ default the client-derived pipeline_summary). */ export function ensureGraphStats( + graph: GraphData, +): GraphData { + return { + ...graph, + pipeline_summary: graph.pipeline_summary, + nodes: graph.nodes.map(ensureNodeStats), + }; +} +/** + * Fill per-month timing percentiles from observations onto existing monthly + * buckets, preserving every other column (notably the carrying-cost + * `total_kg_days`). Dwell steps ship slimmed buckets ({month, n, total_kg_days}) + * and rely on this to rebuild the timing percentiles on load. Buckets with no + * matching observations (e.g. dwell carry-over months) are left untouched. + * When there are no buckets at all, falls back to building them from scratch. + */ function fillMonthlyTiming( + monthly: MonthlyBucket[] | undefined, + obs: Observation[], +): MonthlyBucket[] { + if (!monthly || monthly.length === 0) { + return buildMonthlyFromObservations(obs); + } + const byMonth = new Map(); + for (const observation of obs) { + const month = observation.date.slice(0, 7); + const arr = byMonth.get(month); + if (arr) { + arr.push(observation.value); + } else { + byMonth.set(month, [observation.value]); + } + } + return monthly.map((bucket) => { + const vals = byMonth.get(bucket.month); + if (!vals || vals.length === 0) { + return bucket; + } + const sorted = [...vals].sort((left, right) => left - right); + return { + ...bucket, + mean: round( + sorted.reduce((left, right) => left + right, 0) / sorted.length, + ), + median: round(percentileOf(sorted, 50)), + }; + }); +} +export function deriveTimingFromRecords(step: StepDetail): StepDetail { + if (step.observations.length > 0) { + return step; + } + const valueCol = step.value_col; + const dateCol = step.ref_date_col; + const rows = step.detail_rows?.rows; + if (!valueCol || !dateCol || !rows || rows.length === 0) { + return step; + } + if (step.type === "procurement") { + const derived = deriveProcurementTimingFromRows(rows); + if (derived) { + const values = derived.first.map((observation) => observation.value); + const completeValues = derived.complete.map( + (observation) => observation.value, + ); + return { + ...step, + observations: derived.first, + durations: values, + monthly: buildMonthlyFromObservations(derived.first), + stats: computeStats(values), + complete_timing: { + label: "Full receipt", + observations: derived.complete, + monthly: buildMonthlyFromObservations(derived.complete), + stats: computeStats(completeValues), + }, + }; + } + } + + const obs: Observation[] = []; + for (const row of rows) { + const day = row[dateCol]; + const value = row[valueCol]; + if (typeof value === "number" && typeof day === "string") { + obs.push({ date: day, value }); + } + } + if (obs.length === 0) { + return step; + } + obs.sort((left, right) => + left.date < right.date ? -1 : left.date > right.date ? 1 : 0, + ); + const values = obs.map((observation) => observation.value); + return { + ...step, + observations: obs, + durations: values, + monthly: buildMonthlyFromObservations(obs), + stats: computeStats(values), + }; +} + +/** + * Fill a step's timing + yield/consumption `stats` from observations when + * absent, and guarantee the post-load timing invariant. The wire ships only the + * records-derivable fields (dwell steps keep observations + monthly for + * total_kg_days; pure-timing steps ship neither and rely on + * {@link deriveTimingFromRecords}); `durations` is never shipped. This restores + * `observations`/`durations`/`monthly`/`stats` so every downstream consumer can + * keep reading them directly. + */ +export function ensureStepStats(step: StepDetail): StepDetail { + const derived = deriveTimingFromRecords(step); + const observations = derived.observations; + const base: StepDetail = { + ...derived, + observations, + durations: derived.durations, + monthly: fillMonthlyTiming(derived.monthly, observations), + }; + const next: StepDetail = hasStats(base.stats) + ? { + ...base, + pct_exceeding_plan: pctExceeding(base.observations, base.plan), + } + : { + ...base, + stats: statsFromObservations(base.observations), + pct_exceeding_plan: pctExceeding(base.observations, base.plan), + }; + + if (next.yield_data) { + next.yield_data = ensureSeriesStats(next.yield_data) ?? next.yield_data; + } + if (next.consumption_data) { + const agg = + ensureSeriesStats(next.consumption_data.aggregate) ?? + next.consumption_data.aggregate; + const components = next.consumption_data.components.map( + (column) => ensureSeriesStats(column) ?? column, + ); + next.consumption_data = { + ...next.consumption_data, + aggregate: agg, + components, + }; + } + if (next.complete_timing) { + next.complete_timing = + ensureTimingSeriesStats(next.complete_timing) ?? next.complete_timing; + } + return next; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/observation-fixtures.ts b/apps/hash-frontend/src/pages/supply-chain/shared/observation-fixtures.ts new file mode 100644 index 00000000000..9d523844a4b --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/observation-fixtures.ts @@ -0,0 +1,98 @@ +import { computeStats } from "./stats"; + +import type { + GraphNode, + MonthlyBucket, + Observation, + StepDetail, + StepStats, + TimingSeries, +} from "./types"; + +/** Shared fixtures for the stats / outlier-selection / range-filter tests. */ + +export const emptyStats: StepStats = { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, +}; + +export function obs(month: string, value: number): Observation { + return { date: `${month}-15`, value }; +} + +export function bucket(month: string): MonthlyBucket { + return { month, mean: null, median: null, n: 1 }; +} + +export function stepFrom(observations: Observation[]): StepDetail { + const months = [ + ...new Set(observations.map((observation) => observation.date.slice(0, 7))), + ].sort(); + const values = observations.map((observation) => observation.value); + return { + id: "s1", + label: "Step", + type: "transit", + durations: values, + observations, + monthly: months.map(bucket), + stats: computeStats(values), + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: null, + }; +} + +export function timingSeriesFrom( + observations: Observation[], + label = "Full receipt (PO complete)", +): TimingSeries { + const months = [ + ...new Set(observations.map((observation) => observation.date.slice(0, 7))), + ].sort(); + return { + label, + observations, + monthly: months.map(bucket), + stats: computeStats(observations.map((observation) => observation.value)), + }; +} + +export function makeNode(overrides: Partial = {}): GraphNode { + return { + id: "n1", + label: "Node", + type: "intermediate_dwell", + material: null, + plant: "PL-A", + stats: emptyStats, + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: null, + observations: [ + obs("2026-01", 10), + obs("2026-02", 12), + obs("2026-03", 11), + obs("2026-04", 13), + ], + + monthly: [ + bucket("2026-01"), + bucket("2026-02"), + bucket("2026-03"), + bucket("2026-04"), + ], + + ...overrides, + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/observation-labels.ts b/apps/hash-frontend/src/pages/supply-chain/shared/observation-labels.ts new file mode 100644 index 00000000000..8e10e990f10 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/observation-labels.ts @@ -0,0 +1,137 @@ +import type { StepType } from "./types"; + +export type CountDimension = "timing" | "yield" | "consumption" | "supplier"; + +interface CountContext { + id?: string; + label?: string; + type: StepType; + dimension?: CountDimension; + selectedComponent?: boolean; +} + +interface CountTooltipContext extends CountContext { + count: number; + rangeLabel?: string | null; + nBatches?: number | null; + nMovements?: number | null; +} + +function isDirectShip(ctx: Pick): boolean { + return Boolean( + (ctx.id?.startsWith("direct_ship_") ?? false) || + ctx.label?.toLowerCase().includes("direct-to-customer"), + ); +} + +export function countNoun(ctx: CountContext): string { + if (ctx.dimension === "yield") { + return "production orders"; + } + if (ctx.dimension === "consumption") { + return ctx.selectedComponent ? "component events" : "consumption events"; + } + if (ctx.dimension === "supplier") { + return "schedule lines"; + } + return "events"; +} + +export function shortCountLabel(count: number, ctx: CountContext): string { + return `${count} ${countNoun(ctx)}`; +} + +export function rangeLabel(value?: string | null): string { + if (!value || value === "all") { + return "all time"; + } + if (value === "3m") { + return "the last 3 months"; + } + if (value === "6m") { + return "the last 6 months"; + } + if (value === "12m" || value === "1y") { + return "the last 12 months"; + } + if (value === "2y") { + return "the last 2 years"; + } + return value; +} + +export function dateAnchorLabel(ctx: CountContext): string { + if (ctx.dimension === "yield") { + return "production receipt date"; + } + if (ctx.dimension === "consumption") { + return "consumption posting date"; + } + if (isDirectShip(ctx)) { + return "actual arrival date"; + } + + switch (ctx.type) { + case "procurement": + return "first goods receipt date"; + case "raw_material_dwell": + case "intermediate_dwell": + return "consumption date"; + case "production": + return "schedule start"; + case "qa_hold": + return "production receipt date"; + case "post_qa_ship": + return "QA release date"; + case "transit": + return "hub receipt date"; + case "destination_dwell": + return "hub outbound date"; + default: + return "event date"; + } +} + +function eventMethodology(ctx: CountContext): string { + if (ctx.dimension === "yield") { + return "each production order contributes one receipt-ratio event."; + } + if (ctx.dimension === "consumption") { + return ctx.selectedComponent + ? "each component consumption posting contributes one variance event." + : "component consumption postings are aggregated into consumption events."; + } + if (isDirectShip(ctx)) { + return "each customer delivery contributes one direct-ship event (per delivery, per batch)."; + } + + switch (ctx.type) { + case "procurement": + return "each matched PO goods receipt contributes one lead-time event."; + case "raw_material_dwell": + case "intermediate_dwell": + return "each consumption tranche / goods issue is counted separately."; + case "production": + return "each production schedule campaign contributes one duration event."; + case "qa_hold": + return "each finished-good batch contributes one QA-hold event."; + case "post_qa_ship": + return "each dispatch (customer delivery or hub transfer) contributes one post-QA dwell event."; + case "transit": + return "each hub arrival contributes one transit event."; + case "destination_dwell": + return "each hub dispatch contributes one destination-dwell event."; + default: + return "each source event contributes one timing event."; + } +} + +export function countTooltip(ctx: CountTooltipContext): string { + const label = shortCountLabel(ctx.count, ctx); + const period = rangeLabel(ctx.rangeLabel); + const base = `${label} in ${period}. Filtered by ${dateAnchorLabel(ctx)}; ${eventMethodology(ctx)}`; + if (ctx.nBatches != null && ctx.nMovements != null) { + return `${base} All-time source coverage: ${ctx.nBatches} batches, ${ctx.nMovements} movements.`; + } + return base; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.test.ts new file mode 100644 index 00000000000..4ec3447672c --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.test.ts @@ -0,0 +1,121 @@ +import { describe, expect, it } from "vitest"; + +import { + makeNode, + obs, + stepFrom, + timingSeriesFrom, +} from "./observation-fixtures"; +import { + applyOutlierSelectionToNode, + applyOutlierSelectionToStep, +} from "./outlier-selection"; + +// Characterization tests for the client-side Tukey 1.5x IQR outlier rule. +// Behaviour pinned here MUST survive the contract refactor (the selected-view +// semantics stay even as the duplicated outlier paths were collapsed). + +describe("applyOutlierSelectionToStep", () => { + // One clear high outlier (100) far beyond the Tukey upper fence. + const withOutlier = () => + stepFrom([ + obs("2026-01", 10), + obs("2026-01", 11), + obs("2026-02", 12), + obs("2026-02", 13), + obs("2026-03", 14), + obs("2026-03", 15), + obs("2026-04", 16), + obs("2026-04", 17), + obs("2026-04", 100), + ]); + + it("drops out-of-fence points and recomputes stats when excluding outliers", () => { + const selected = applyOutlierSelectionToStep(withOutlier(), true); + expect(selected.durations).toEqual([10, 11, 12, 13, 14, 15, 16, 17]); + expect(selected.stats.n).toBe(8); + expect(selected.excluded_count).toBe(1); + expect(selected.excluded_pct).toBeCloseTo(100 / 9, 1); + }); + + it("returns the full series unchanged when including outliers", () => { + const selected = applyOutlierSelectionToStep(withOutlier(), false); + expect(selected.stats.n).toBe(9); + expect(selected.excluded_count).toBe(0); + expect(selected.excluded_pct).toBe(0); + }); + + it("excludes nothing for a tight distribution", () => { + const selected = applyOutlierSelectionToStep( + stepFrom([ + obs("2026-01", 10), + obs("2026-02", 12), + obs("2026-03", 11), + obs("2026-04", 13), + ]), + true, + ); + expect(selected.stats.n).toBe(4); + expect(selected.excluded_count).toBe(0); + }); + + it("outlier-filters the secondary complete_timing series independently of the headline", () => { + const step = stepFrom([ + obs("2026-01", 10), + obs("2026-02", 12), + obs("2026-03", 11), + obs("2026-04", 13), + ]); + // Headline is tight; the secondary series carries one clear high outlier. + step.complete_timing = timingSeriesFrom([ + obs("2026-01", 20), + obs("2026-01", 21), + obs("2026-02", 22), + obs("2026-02", 23), + obs("2026-03", 24), + obs("2026-03", 25), + obs("2026-04", 26), + obs("2026-04", 27), + obs("2026-04", 200), + ]); + const selected = applyOutlierSelectionToStep(step, true); + // Headline untouched, secondary loses its outlier. + expect(selected.stats.n).toBe(4); + expect(selected.excluded_count).toBe(0); + expect(selected.complete_timing?.stats.n).toBe(8); + expect( + selected.complete_timing?.observations.map( + (observation) => observation.value, + ), + ).not.toContain(200); + }); + + it("leaves complete_timing untouched when including outliers", () => { + const step = stepFrom([obs("2026-01", 10), obs("2026-02", 12)]); + step.complete_timing = timingSeriesFrom([ + obs("2026-01", 20), + obs("2026-02", 200), + ]); + const selected = applyOutlierSelectionToStep(step, false); + expect(selected.complete_timing?.stats.n).toBe(2); + }); +}); + +describe("applyOutlierSelectionToNode", () => { + // Shipped v1 data carries a single base series (no raw_*/filtered_*), so today + // both toggle states return the base series untouched. The fixture uses a tight + // distribution so this invariant also holds once Tukey IQR filtering lands. + it("returns the base series when including outliers", () => { + const out = applyOutlierSelectionToNode(makeNode(), false); + expect(out.observations?.map((observation) => observation.value)).toEqual([ + 10, 12, 11, 13, + ]); + }); + + it("returns the base series when excluding outliers and none lie beyond the fences", () => { + const out = applyOutlierSelectionToNode(makeNode(), true); + expect(out.observations?.map((observation) => observation.value)).toEqual([ + 10, 12, 11, 13, + ]); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.ts b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.ts new file mode 100644 index 00000000000..84f6d2f3e49 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection.ts @@ -0,0 +1,257 @@ +import { computeIqrFences, partitionByFences } from "./outlier-selection/iqr"; +import { computeStats, percentileOf, round } from "./stats"; + +import type { + GraphNode, + StepDetail, + Observation, + MonthlyBucket, + StepStats, + YieldData, + ConsumptionData, + ComponentConsumption, + TimingSeries, +} from "./types"; + +/** + * Apply the client-side Tukey 1.5x IQR outlier rule to a graph node. + * + * When `excludeOutliers` is true, fences are computed from the shipped + * `observations`, out-of-bound points are dropped, and `stats`/`monthly` are + * recomputed from the kept series (cost columns on each monthly bucket are + * preserved -- inventory kg-days are independent of duration outliers). + * `excluded_count`/`excluded_pct` describe the full-series exclusion. When + * false (or with too few points), the base series is returned unchanged. + */ + +/** + * Recompute per-month timing values (mean/median/n) from a kept observation set, + * preserving each bucket's non-timing columns (kg-days, qty, variance). Months + * with no kept observations keep their bucket with null timing and `n = 0`. + */ +function rebuildMonthlyTiming( + original: MonthlyBucket[], + keptObs: Observation[], +): MonthlyBucket[] { + if (original.length === 0) { + return original; + } + const byMonth = new Map(); + for (const observation of keptObs) { + const month = observation.date.slice(0, 7); + const arr = byMonth.get(month); + if (arr) { + arr.push(observation.value); + } else { + byMonth.set(month, [observation.value]); + } + } + return original.map((bucket) => { + const vals = byMonth.get(bucket.month); + if (!vals || vals.length === 0) { + return { ...bucket, mean: null, median: null, n: 0 }; + } + const sorted = [...vals].sort((left, right) => left - right); + return { + ...bucket, + mean: round( + sorted.reduce((left, right) => left + right, 0) / sorted.length, + ), + median: round(percentileOf(sorted, 50)), + n: sorted.length, + }; + }); +} + +/** Drop Tukey-IQR outliers from a bare observation array (over its own values). */ function outlierFilterObservations( + obs: Observation[], +): Observation[] { + if (obs.length === 0) { + return obs; + } + const { kept } = partitionByFences( + obs, + computeIqrFences(obs.map((observation) => observation.value)), + ); + return kept; +} +/** + * A series shaped like the per-family blocks shipped on a step + * (`yield_data`, `consumption_data.aggregate`, each consumption component): + * a raw observation series plus the precomputed views derived from it. + */ export function applyOutlierSelectionToNode( + node: GraphNode, + excludeOutliers: boolean, +): GraphNode { + if (!excludeOutliers) { + return { ...node, excluded_count: 0, excluded_pct: 0 }; + } // Timing series (durations). Does not short-circuit the per-observation + // yield/consumption series passes below (a node may have no timing outliers + // but still carry yield/consumption outliers, or vice versa). + const observations = node.observations ?? []; + let timing: Partial = {}; + let excludedCount = 0; + if (observations.length > 0) { + const { kept, excluded } = partitionByFences( + observations, + computeIqrFences(observations.map((observation) => observation.value)), + ); + if (excluded.length > 0) { + timing = { + stats: computeStats(kept.map((observation) => observation.value)), + observations: kept, + monthly: node.monthly + ? rebuildMonthlyTiming(node.monthly, kept) + : node.monthly, + }; + excludedCount = excluded.length; + } + } + return { + ...node, + ...timing, + yield_series: node.yield_series + ? { + ...node.yield_series, + observations: outlierFilterObservations( + node.yield_series.observations, + ), + } + : node.yield_series, + consumption_series: node.consumption_series + ? { + ...node.consumption_series, + observations: outlierFilterObservations( + node.consumption_series.observations, + ), + } + : node.consumption_series, + excluded_count: excludedCount, + excluded_pct: + observations.length > 0 + ? round((100 * excludedCount) / observations.length) + : 0, + }; +} +interface SeriesLike { + values: number[]; + observations: Observation[]; + monthly: MonthlyBucket[]; + stats: StepStats; +} +/** + * Drop Tukey-IQR outliers from one family series (computed over its own value + * distribution) and recompute `values`/`stats`/`monthly` from the kept points. + * Returns the series unchanged when there is nothing to exclude. Non-timing + * monthly columns (kg-days, qty, variance) are preserved via the spread in + * {@link rebuildMonthlyTiming}. + */ function applyOutlierToSeries(series: T): T { + const observations = series.observations; + if (observations.length === 0) { + return series; + } + const { kept, excluded } = partitionByFences( + observations, + computeIqrFences(observations.map((observation) => observation.value)), + ); + if (excluded.length === 0) { + return series; + } + const values = kept.map((observation) => observation.value); + return { + ...series, + values, + observations: kept, + monthly: rebuildMonthlyTiming(series.monthly, kept), + stats: computeStats(values), + }; +} +/** Outlier-filter the yield series (receipt-ratio %) in place of its raw points. */ function applyOutlierToYield( + yd: YieldData, +): YieldData { + return applyOutlierToSeries(yd); +} +/** + * Outlier-filter the consumption block: each component series and the aggregate + * series are partitioned independently. Downstream windowing recomputes the + * aggregate `weighted_variance_pct` from whatever observations remain, so + * dropping outlier points here makes that window-aware metric outlier-aware too. + */ function applyOutlierToConsumption(cd: ConsumptionData): ConsumptionData { + const components = cd.components.map((column) => + applyOutlierToSeries(column), + ); + const aggregate = applyOutlierToSeries(cd.aggregate); + return { ...cd, components, aggregate }; +} +/** + * Outlier-filter a secondary {@link TimingSeries} (e.g. procurement's + * full-receipt lead time) over its own value distribution, recomputing + * `monthly`/`stats` from the kept points. Returned unchanged when there is + * nothing to exclude. Independent of the headline series so the two can have + * different fences. + */ function applyOutlierToTimingSeries(ts: TimingSeries): TimingSeries { + const observations = ts.observations; + if (observations.length === 0) { + return ts; + } + const { kept, excluded } = partitionByFences( + observations, + computeIqrFences(observations.map((observation) => observation.value)), + ); + if (excluded.length === 0) { + return ts; + } + return { + ...ts, + observations: kept, + monthly: rebuildMonthlyTiming(ts.monthly, kept), + stats: computeStats(kept.map((observation) => observation.value)), + }; +} +/** Step-level counterpart of {@link applyOutlierSelectionToNode}. */ export function applyOutlierSelectionToStep( + step: StepDetail, + excludeOutliers: boolean, +): StepDetail { + if (!excludeOutliers) { + return { ...step, excluded_count: 0, excluded_pct: 0 }; + } // Timing series (durations). May have nothing to exclude even when the + // yield/consumption families do, so the per-family passes below run + // independently of this one. + const observations = step.observations; + let timing: Partial = {}; + let excludedCount = 0; + if (observations.length > 0) { + const { kept, excluded } = partitionByFences( + observations, + computeIqrFences(observations.map((observation) => observation.value)), + ); + if (excluded.length > 0) { + const values = kept.map((observation) => observation.value); + timing = { + durations: values, + observations: kept, + monthly: rebuildMonthlyTiming(step.monthly, kept), + stats: computeStats(values), + }; + excludedCount = excluded.length; + } + } + return { + ...step, + ...timing, + yield_data: step.yield_data + ? applyOutlierToYield(step.yield_data) + : step.yield_data, + consumption_data: step.consumption_data + ? applyOutlierToConsumption(step.consumption_data) + : step.consumption_data, + complete_timing: step.complete_timing + ? applyOutlierToTimingSeries(step.complete_timing) + : step.complete_timing, + excluded_count: excludedCount, + excluded_pct: + observations.length > 0 + ? round((100 * excludedCount) / observations.length) + : 0, + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.test.ts new file mode 100644 index 00000000000..9064d80b23f --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.test.ts @@ -0,0 +1,61 @@ +import { describe, expect, it } from "vitest"; + +import { IQR_K, computeIqrFences, partitionByFences } from "./iqr"; + +import type { Observation } from "../types"; + +function obs(value: number): Observation { + return { date: "2026-01-15", value }; +} + +describe("computeIqrFences", () => { + it("computes Tukey 1.5x fences from quartiles", () => { + // [10..17, 100]: Q1=12, Q3=16, IQR=4 -> [12 - 6, 16 + 6] = [6, 22] + const fences = computeIqrFences([10, 11, 12, 13, 14, 15, 16, 17, 100]); + expect(fences).not.toBeNull(); + expect(fences!.lower).toBeCloseTo(6, 6); + expect(fences!.upper).toBeCloseTo(22, 6); + }); + + it("honours a custom k multiplier", () => { + const fences = computeIqrFences([10, 11, 12, 13, 14, 15, 16, 17, 100], 3); + // IQR=4 -> [12 - 12, 16 + 12] = [0, 28] + expect(fences!.lower).toBeCloseTo(0, 6); + expect(fences!.upper).toBeCloseTo(28, 6); + }); + + it("returns null for fewer than 4 points", () => { + expect(computeIqrFences([1, 2, 3])).toBeNull(); + expect(IQR_K).toBe(1.5); + }); +}); + +describe("partitionByFences", () => { + it("splits observations on the fences", () => { + const fences = computeIqrFences([10, 11, 12, 13, 14, 15, 16, 17, 100]); + const { kept, excluded } = partitionByFences( + [10, 11, 12, 13, 14, 15, 16, 17, 100].map(obs), + fences, + ); + expect(kept.map((observation) => observation.value)).toEqual([ + 10, 11, 12, 13, 14, 15, 16, 17, + ]); + expect(excluded.map((observation) => observation.value)).toEqual([100]); + }); + + it("keeps everything for a tight distribution (no points beyond fences)", () => { + const values = [10, 11, 12, 13]; + const { kept, excluded } = partitionByFences( + values.map(obs), + computeIqrFences(values), + ); + expect(kept).toHaveLength(4); + expect(excluded).toHaveLength(0); + }); + + it("keeps everything when fences are null", () => { + const { kept, excluded } = partitionByFences([obs(1), obs(2)], null); + expect(kept).toHaveLength(2); + expect(excluded).toHaveLength(0); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.ts b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.ts new file mode 100644 index 00000000000..71e80fa2e37 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/outlier-selection/iqr.ts @@ -0,0 +1,73 @@ +import type { Observation } from "../types"; + +/** Tukey fence multiplier for the standard 1.5x IQR outlier rule. */ +export const IQR_K = 1.5; + +export interface IqrFences { + lower: number; + upper: number; +} + +function percentile(sorted: number[], product: number): number { + if (sorted.length === 0) { + throw new Error("Cannot compute a percentile of an empty series"); + } + const count = sorted.length; + const idx = (product / 100) * (count - 1); + const lo = Math.floor(idx); + const hi = Math.ceil(idx); + const low = sorted[lo]; + const high = sorted[hi]; + if (low === undefined || high === undefined) { + throw new Error("Percentile index was outside the provided series"); + } + if (lo === hi) { + return low; + } + return low + (high - low) * (idx - lo); +} + +/** + * Tukey fences `[Q1 - k*IQR, Q3 + k*IQR]` (quartiles via linear interpolation, + * matching `computeStats`). Returns `null` for fewer than 4 points, where the + * quartile spread is too unstable to flag outliers reliably. + */ +export function computeIqrFences( + values: number[], + key = IQR_K, +): IqrFences | null { + if (values.length < 4) { + return null; + } + const sorted = [...values].sort((left, right) => left - right); + const q1 = percentile(sorted, 25); + const q3 = percentile(sorted, 75); + const iqr = q3 - q1; + return { lower: q1 - key * iqr, upper: q3 + key * iqr }; +} + +/** + * Split observations into those inside the fences (`kept`) and outside + * (`excluded`). With `null` fences (too few points) everything is kept. + */ +export function partitionByFences( + observations: Observation[], + fences: IqrFences | null, +): { kept: Observation[]; excluded: Observation[] } { + if (!fences) { + return { kept: [...observations], excluded: [] }; + } + const kept: Observation[] = []; + const excluded: Observation[] = []; + for (const observation of observations) { + if ( + observation.value >= fences.lower && + observation.value <= fences.upper + ) { + kept.push(observation); + } else { + excluded.push(observation); + } + } + return { kept, excluded }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/period-trends.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/period-trends.test.ts new file mode 100644 index 00000000000..59bf4aad119 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/period-trends.test.ts @@ -0,0 +1,232 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { + computeCostComparison, + computeCostTrend, + computePeriodDeltas, + computeTimingTrend, + computeTrend, + median, + percentChange, + periodCutoffs, + rangeMonths, + trendDirection, +} from "./period-trends"; + +import type { + CostData, + MonthlyBucket, + Observation, + SiteNode, + StepStats, +} from "./types"; + +function obs(month: string, value: number): Observation { + return { date: `${month}-15`, value }; +} + +const zeroStats: StepStats = { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, +}; + +function cost(unitPrice: number | null): CostData { + return { unit_price: unitPrice, currency: "EUR" }; +} + +function kgDayMonth( + month: string, + totalKgDays: number, + count = 1, +): MonthlyBucket { + return { + month, + mean: null, + median: null, + n: count, + total_kg_days: totalKgDays, + }; +} + +function siteNode(overrides: Partial): SiteNode { + return { + id: "n", + label: "Node", + type: "intermediate_dwell", + material: null, + plant: "PL-A", + stats: zeroStats, + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: null, + products: [{ id: "p1", name: "P1" }], + ...overrides, + }; +} + +describe("rangeMonths", () => { + it("maps tokens to month counts", () => { + expect(rangeMonths("3m")).toBe(3); + expect(rangeMonths("6m")).toBe(6); + expect(rangeMonths("12m")).toBe(12); + }); +}); + +describe("median", () => { + it("returns null on empty", () => expect(median([])).toBeNull()); + it("handles odd length", () => expect(median([3, 1, 2])).toBe(2)); + it("averages the two middle values for even length", () => + expect(median([1, 2, 3, 4])).toBe(2.5)); +}); + +describe("percentChange", () => { + it("computes a relative change", () => + expect(percentChange(120, 100)).toBeCloseTo(20, 6)); + it("returns null when previous is zero or a value is null", () => { + expect(percentChange(10, 0)).toBeNull(); + expect(percentChange(null, 100)).toBeNull(); + expect(percentChange(100, null)).toBeNull(); + }); +}); + +describe("trendDirection", () => { + it("classifies within the +/-5% flat band", () => { + expect(trendDirection(null)).toBe("unknown"); + expect(trendDirection(4.9)).toBe("flat"); + expect(trendDirection(-4.9)).toBe("flat"); + expect(trendDirection(6)).toBe("worsening"); + expect(trendDirection(-6)).toBe("improving"); + }); +}); + +describe("period helpers anchored to a fixed clock", () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-06-15T00:00:00Z")); + }); + afterEach(() => vi.useRealTimers()); + + it("periodCutoffs derives the current and previous windows", () => { + // now=2026-06, 6m -> current 2026-01..2026-06; previous 2025-07..2025-12 + expect(periodCutoffs("6m")).toEqual({ + currentFrom: "2026-01", + previousFrom: "2025-07", + previousTo: "2025-12", + }); + }); + + it("computeTrend compares current vs previous medians (6m window)", () => { + const observations: Observation[] = [ + obs("2025-07", 40), + obs("2025-09", 60), + obs("2026-01", 10), + obs("2026-03", 20), + ]; + + const trend = computeTrend(observations, "6m"); + expect(trend.currentValue).toBe(15); + expect(trend.previousValue).toBe(50); + expect(trend.currentN).toBe(2); + expect(trend.previousN).toBe(2); + expect(trend.pctChange).toBeCloseTo(-70, 6); + expect(trend.direction).toBe("improving"); + }); + + it("computeTrend handles the 12m window", () => { + const observations: Observation[] = [ + obs("2024-08", 100), + obs("2025-02", 100), + obs("2025-08", 120), + obs("2026-02", 120), + ]; + + const trend = computeTrend(observations, "12m"); + expect(trend.currentValue).toBe(120); + expect(trend.previousValue).toBe(100); + expect(trend.pctChange).toBeCloseTo(20, 6); + expect(trend.direction).toBe("worsening"); + }); + + it("computeTrend reports flat within the band and unknown on zero-previous", () => { + const flat = computeTrend([obs("2025-07", 102), obs("2026-01", 100)], "6m"); + expect(flat.direction).toBe("flat"); + const zeroPrev = computeTrend( + [obs("2025-07", 0), obs("2026-01", 10)], + "6m", + ); + expect(zeroPrev.previousValue).toBe(0); + expect(zeroPrev.pctChange).toBeNull(); + expect(zeroPrev.direction).toBe("unknown"); + }); + + it("computeTimingTrend mirrors computeTrend over a node's observations", () => { + const node = siteNode({ + observations: [ + obs("2025-07", 40), + obs("2025-09", 60), + obs("2026-01", 10), + obs("2026-03", 20), + ], + }); + const threshold = computeTimingTrend(node, "6m"); + expect(threshold.currentValue).toBe(15); + expect(threshold.previousValue).toBe(50); + expect(threshold.pctChange).toBeCloseTo(-70, 6); + }); + + it("computeCostTrend totals carrying cost across windows", () => { + const node = siteNode({ + cost: cost(100), + monthly: [kgDayMonth("2025-07", 1000), kgDayMonth("2026-01", 500)], + }); + const threshold = computeCostTrend(node, "6m", 0.1, 0.336); + // current window has 2026-01 only, previous window has 2025-07 only + expect(threshold.currentTotal).toBeCloseTo( + 500 * (100 * (0.1 / 365) + 0.336 / 1000), + 6, + ); + expect(threshold.previousTotal).toBeCloseTo( + 1000 * (100 * (0.1 / 365) + 0.336 / 1000), + 6, + ); + expect(threshold.currentN).toBe(1); + expect(threshold.previousN).toBe(1); + }); + + it("computeCostComparison returns the delta vs the previous window", () => { + const monthly = [kgDayMonth("2025-07", 1000), kgDayMonth("2026-01", 2000)]; + const cmp = computeCostComparison(monthly, 100, 0.1, 0.336, "6m"); + // current = 2000 units, previous = 1000 units -> +100% + expect(cmp.delta).toBeCloseTo(100, 6); + expect(cmp.previousTotal).toBeCloseTo( + 1000 * (100 * (0.1 / 365) + 0.336 / 1000), + 6, + ); + }); + + it("computePeriodDeltas produces per-stat percentage deltas", () => { + const observations: Observation[] = [ + // previous window 2025-07..2025-12 + obs("2025-07", 10), + obs("2025-08", 20), + // current window 2026-01..2026-06 + obs("2026-01", 20), + obs("2026-02", 40), + ]; + + const deltas = computePeriodDeltas(observations, "6m"); + expect(deltas.previousStats?.n).toBe(2); + expect(deltas.medianPctChange).toBeCloseTo(100, 6); + expect(deltas.currentRange).not.toBeNull(); + expect(deltas.previousRange).not.toBeNull(); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/period-trends.ts b/apps/hash-frontend/src/pages/supply-chain/shared/period-trends.ts new file mode 100644 index 00000000000..22f02bd4627 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/period-trends.ts @@ -0,0 +1,316 @@ +import { computePeriodCost } from "./cost"; +import { type BaseMeasure, statOf } from "./measure-context"; +import { computeStats } from "./stats"; +import { + type TimeRange, + cutoffForRange, + monthKeyMonthsAgo, + rangeMonths, +} from "./time-range"; + +import type { MonthlyBucket, Observation, SiteNode, StepStats } from "./types"; + +export { rangeMonths }; + +/** + * Current/previous period boundaries (YYYY-MM) for a range, anchored to today. + * The previous window is the equal-length span immediately before the current one. + * Single source of truth for the period-over-period comparisons across the app. + */ +export function periodCutoffs(range: TimeRange): { + currentFrom: string; + previousFrom: string; + previousTo: string; +} { + const months = rangeMonths(range); + const currentFrom = cutoffForRange(range); + const previousTo = monthKeyMonthsAgo(months); + const previousFrom = monthKeyMonthsAgo(months * 2 - 1); + + return { currentFrom, previousFrom, previousTo }; +} + +/** Median of a list of values (null on empty). */ +export function median(values: number[]): number | null { + if (values.length === 0) { + return null; + } + const sorted = [...values].sort((left, right) => left - right); + const mid = Math.floor(sorted.length / 2); + const upper = sorted[mid]; + if (upper === undefined) { + throw new Error("Median index was outside the provided series"); + } + if (sorted.length % 2 === 1) { + return upper; + } + const lower = sorted[mid - 1]; + if (lower === undefined) { + throw new Error("Median lower index was outside the provided series"); + } + return (lower + upper) / 2; +} + +/** Percentage change current-vs-previous (null when undefined or previous is zero). */ +export function percentChange( + current: number | null, + previous: number | null, +): number | null { + if (current == null || previous == null || previous === 0) { + return null; + } + return ((current - previous) / previous) * 100; +} + +export type TrendDirection = "improving" | "worsening" | "flat" | "unknown"; + +/** Classify a percentage change: <5% magnitude is flat, null is unknown. */ +export function trendDirection(pctChange: number | null): TrendDirection { + if (pctChange == null || Math.abs(pctChange) < 5) { + return pctChange == null ? "unknown" : "flat"; + } + return pctChange > 0 ? "worsening" : "improving"; +} + +export interface BaseMeasureTrend { + pctChange: number | null; + /** The current-window value of the selected base measure. */ + currentValue: number | null; + /** The previous-window value of the selected base measure. */ + previousValue: number | null; + currentN: number; + previousN: number; + direction: TrendDirection; +} + +/** Timing trend (current vs previous window) for the selected base measure. */ +export function computeTrend( + observations: Observation[], + range: TimeRange, + measure: BaseMeasure = "median", +): BaseMeasureTrend { + const { currentFrom, previousFrom, previousTo } = periodCutoffs(range); + const currentValues = observations + .filter((observation) => observation.date.slice(0, 7) >= currentFrom) + .map((observation) => observation.value); + const previousValues = observations + .filter((observation) => { + const month = observation.date.slice(0, 7); + return month >= previousFrom && month <= previousTo; + }) + .map((observation) => observation.value); + const currentValue = statOf(currentValues, measure); + const previousValue = statOf(previousValues, measure); + const pctChange = percentChange(currentValue, previousValue); + + return { + pctChange, + currentValue, + previousValue, + currentN: currentValues.length, + previousN: previousValues.length, + direction: trendDirection(pctChange), + }; +} + +export interface TimingTrend { + pctChange: number | null; + currentValue: number | null; + previousValue: number | null; + currentN: number; + previousN: number; +} + +/** Timing trend for a site node's shipped observations, for the selected measure. */ +export function computeTimingTrend( + node: SiteNode, + timeRange: TimeRange, + measure: BaseMeasure = "median", +): TimingTrend { + const trend = computeTrend(node.observations ?? [], timeRange, measure); + return { + pctChange: trend.pctChange, + currentValue: trend.currentValue, + previousValue: trend.previousValue, + currentN: trend.currentN, + previousN: trend.previousN, + }; +} + +export interface CostTrend { + pctChange: number | null; + currentTotal: number | null; + previousTotal: number | null; + currentN: number; + previousN: number; +} + +/** Carrying-cost trend for a site node over the current vs previous window. */ +export function computeCostTrend( + node: SiteNode, + timeRange: TimeRange, + waccRate: number, + storageCost: number, +): CostTrend { + const monthly = + node.monthly?.filter((month) => month.total_kg_days != null) ?? []; + if (monthly.length === 0) { + return { + pctChange: null, + currentTotal: null, + previousTotal: null, + currentN: 0, + previousN: 0, + }; + } + const { currentFrom, previousFrom, previousTo } = periodCutoffs(timeRange); + const sumCost = (from: string, to?: string) => { + const buckets = monthly.filter( + (month) => month.month >= from && (to == null || month.month <= to), + ); + if (buckets.length === 0) { + return { total: null as number | null, n: 0 }; + } + const total = computePeriodCost( + buckets, + node.cost?.unit_price, + waccRate, + storageCost, + ); + return { total, n: buckets.reduce((sum, month) => sum + month.n, 0) }; + }; + const current = sumCost(currentFrom); + const previous = sumCost(previousFrom, previousTo); + return { + pctChange: percentChange(current.total, previous.total), + currentTotal: current.total, + previousTotal: previous.total, + currentN: current.n, + previousN: previous.n, + }; +} + +export interface PeriodComparison { + medianPctChange: number | null; + statDeltas: Record; + previousStats: StepStats | null; + currentRange: { from: string; to: string } | null; + previousRange: { from: string; to: string } | null; +} + +/** Full stat-by-stat deltas (mean/median/std/p75/p95/max) current vs previous. */ +export function computePeriodDeltas( + observations: Observation[], + range: TimeRange, +): PeriodComparison { + const { currentFrom, previousFrom, previousTo } = periodCutoffs(range); + + const currentObs = observations.filter( + (observation) => observation.date.slice(0, 7) >= currentFrom, + ); + const prevObs = observations.filter((observation) => { + const month = observation.date.slice(0, 7); + return month >= previousFrom && month <= previousTo; + }); + + const currentStats = computeStats( + currentObs.map((observation) => observation.value), + ); + const prevStats = computeStats( + prevObs.map((observation) => observation.value), + ); + + const pctDelta = (curr: number, prev: number) => { + if (prev === 0) { + return null; + } + return ((curr - prev) / prev) * 100; + }; + + const hasPrev = prevStats.n > 0; + const hasCurrent = currentStats.n > 0; + + const now = new Date().toISOString().slice(0, 7); + const currentRange = hasCurrent ? { from: currentFrom, to: now } : null; + const previousRange = hasPrev ? { from: previousFrom, to: previousTo } : null; + + if (!hasCurrent || !hasPrev) { + return { + medianPctChange: null, + statDeltas: {}, + previousStats: hasPrev ? prevStats : null, + currentRange, + previousRange, + }; + } + + const keys: (keyof StepStats)[] = [ + "min", + "mean", + "median", + "std", + "p75", + "p95", + "max", + ]; + + const statDeltas: Record = {}; + for (const key of keys) { + statDeltas[key] = pctDelta( + currentStats[key] as number, + prevStats[key] as number, + ); + } + + return { + medianPctChange: statDeltas.median ?? null, + statDeltas, + previousStats: prevStats, + currentRange, + previousRange, + }; +} + +/** Carrying-cost delta (current vs previous window) from unfiltered monthly cost buckets. */ +export function computeCostComparison( + unfilteredCostMonthly: MonthlyBucket[] | undefined, + unitPrice: number | null | undefined, + waccRate: number, + storageCost: number, + range: TimeRange, +): { delta: number | null; previousTotal: number | null } { + if (!unfilteredCostMonthly || unfilteredCostMonthly.length === 0) { + return { delta: null, previousTotal: null }; + } + const { currentFrom, previousFrom, previousTo } = periodCutoffs(range); + const currentMonths = unfilteredCostMonthly.filter( + (month) => month.month >= currentFrom, + ); + const prevMonths = unfilteredCostMonthly.filter( + (month) => month.month >= previousFrom && month.month <= previousTo, + ); + + if (currentMonths.length === 0 || prevMonths.length === 0) { + return { delta: null, previousTotal: null }; + } + + const currentTotal = computePeriodCost( + currentMonths, + unitPrice, + waccRate, + storageCost, + ); + const prevTotal = computePeriodCost( + prevMonths, + unitPrice, + waccRate, + storageCost, + ); + if (prevTotal === 0) { + return { delta: null, previousTotal: prevTotal }; + } + return { + delta: ((currentTotal - prevTotal) / prevTotal) * 100, + previousTotal: prevTotal, + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/planning-param.ts b/apps/hash-frontend/src/pages/supply-chain/shared/planning-param.ts new file mode 100644 index 00000000000..d8d5c1d8396 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/planning-param.ts @@ -0,0 +1,31 @@ +/** + * Tooltip helpers for planning parameter chips. + * + * The planning parameter is the system's planned time for a step. Which planned + * time applies depends on the step type: + * - Procurement / Transit → planned delivery time (days) + * - Production → goods-receipt processing time (days) + * - Upstream production → in-house production time (days) + * + * `plan_note` on the graph node is set by generate_data.py only when the + * planned time is not the default planned delivery time. + */ + +export function planSourceLabel(planNote: string | null | undefined): string { + if (planNote) { + return `Planning parameter — ${planNote}`; + } + return "Planning parameter (planned delivery time)"; +} + +export function pctChangeTooltip( + pctChange: number, + plan: number, + measureLabel = "Median", +): string { + const abs = Math.abs(pctChange).toFixed(0); + if (pctChange > 0) { + return `${measureLabel} exceeds the ${plan}d planning parameter by ${abs}%`; + } + return `${measureLabel} is ${abs}% below the ${plan}d planning parameter`; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/plant-label.ts b/apps/hash-frontend/src/pages/supply-chain/shared/plant-label.ts new file mode 100644 index 00000000000..95479c9dd16 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/plant-label.ts @@ -0,0 +1,40 @@ +/** + * Compact, display-friendly plant labels for tight UI surfaces (the E2E route + * picker and the coverage line). + * + * Plant names are resolved at runtime from the loaded data (the generator + * ships the full description, e.g. a corporate legal name plus the plant code). + * This helper only trims generic corporate/legal boilerplate so the displayed + * string is shorter -- it contains no hardcoded, site- or client-specific data. + */ + +/** Generic corporate/legal form tokens stripped from plant descriptions. */ +const BOILERPLATE = + /\b(corp|co|inc|llc|ltd|gmbh|ag|kg|kk|sa|bv|nv|plc|pte|the)\b\.?/gi; + +/** + * Return a short `"Name (CODE)"` label for a plant by trimming generic + * corporate boilerplate from the data-provided `fullLabel`. Falls back to the + * bare uppercase code when there is no usable name (e.g. unresolved data). + */ +export function shortPlantLabel( + code: string, + fullLabel?: string | null, +): string { + const codeU = code.toUpperCase(); + + if (fullLabel) { + const name = fullLabel + // Drop a trailing "(CODE)" suffix the generator appended. + .replace(new RegExp(`\\s*\\(${codeU}\\)\\s*$`, "i"), "") + .replace(BOILERPLATE, " ") + .replace(/\s+([,.)])/g, "$1") + .replace(/\s+/g, " ") + .trim(); + if (name) { + return `${name} (${codeU})`; + } + } + + return codeU; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis-context.ts b/apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis-context.ts new file mode 100644 index 00000000000..3bff6ea0043 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis-context.ts @@ -0,0 +1,40 @@ +import { createContext, useContext } from "react"; + +/** + * Which procurement lead-time series drives the *headline* timing everywhere it + * is recomputed client-side (product card badge, site planning deviation / + * bad-param counts, and the step slideover's primary distribution): + * + * - "first": PO date -> first goods receipt. + * - "complete": PO date -> last goods receipt (full-receipt / PO-complete). + * + * Product/site nodes derive the active basis from combined first/last receipt + * observations; step details derive both bases by grouping line rows by PO. + * Every non-procurement step type ignores it. Defaults to "first". + */ +export type ProcurementBasis = "first" | "complete"; + +export const PROCUREMENT_BASES: readonly ProcurementBasis[] = [ + "first", + "complete", +]; + +/** Short label for the toolbar control + tooltips. */ +export const PROCUREMENT_BASIS_LABELS: Record = { + first: "First receipt", + complete: "Full receipt", +}; + +interface ProcurementBasisCtx { + basis: ProcurementBasis; + setBasis: (basis: ProcurementBasis) => void; +} + +export const ProcurementBasisContext = createContext({ + basis: "first", + setBasis: () => {}, +}); + +export function useProcurementBasis() { + return useContext(ProcurementBasisContext); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis.test.ts new file mode 100644 index 00000000000..7bf2f60203f --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/procurement-basis.test.ts @@ -0,0 +1,140 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { ensureNodeStats } from "./normalize-contract"; +import { + makeNode, + obs, + stepFrom, + timingSeriesFrom, +} from "./observation-fixtures"; +import { + applyProcurementBasisToNode, + applyProcurementBasisToStep, + filterGraphNodeByDateRange, +} from "./range-filter"; + +import type { GraphNode, StepDetail } from "./types"; + +// Combined first/last receipt observations, so a basis swap is observable from a +// single series. +function procurementNode(): GraphNode { + return ensureNodeStats( + makeNode({ + id: "procurement_x", + type: "procurement", + observations: [ + { + first_receipt_date: "2026-01-01", + first_receipt_value: 8, + last_receipt_date: "2026-01-24", + last_receipt_value: 24, + }, + { + first_receipt_date: "2026-02-01", + first_receipt_value: 10, + last_receipt_date: "2026-02-26", + last_receipt_value: 26, + }, + { + first_receipt_date: "2026-03-01", + first_receipt_value: 9, + last_receipt_date: "2026-03-25", + last_receipt_value: 25, + }, + { + first_receipt_date: "2026-04-01", + first_receipt_value: 11, + last_receipt_date: "2026-04-27", + last_receipt_value: 27, + }, + ] as unknown as GraphNode["observations"], + monthly: [], + }), + ); +} + +function procurementStep(): StepDetail { + const step = stepFrom([ + obs("2026-01", 8), + obs("2026-02", 10), + obs("2026-03", 9), + obs("2026-04", 11), + ]); + step.type = "procurement"; + step.id = "procurement_x"; + step.complete_timing = timingSeriesFrom([ + obs("2026-01", 24), + obs("2026-02", 26), + obs("2026-03", 25), + obs("2026-04", 27), + ]); + return step; +} + +describe("applyProcurementBasisToNode", () => { + it("is a no-op for the first-receipt basis", () => { + const node = procurementNode(); + expect( + applyProcurementBasisToNode(node, "first").observations?.map( + (observation) => observation.value, + ), + ).toEqual([8, 10, 9, 11]); + }); + + it("promotes the full-receipt series from combined observations for the complete basis", () => { + const out = applyProcurementBasisToNode(procurementNode(), "complete"); + expect(out.stats.median).toBe(25.5); + expect(out.observations?.map((observation) => observation.value)).toEqual([ + 24, 26, 25, 27, + ]); + expect(out).not.toHaveProperty("complete_series"); + }); + + it("ignores non-procurement nodes and procurement nodes without full-receipt data", () => { + const plain = makeNode({ type: "transit" }); + expect(applyProcurementBasisToNode(plain, "complete")).toBe(plain); + const bare = makeNode({ type: "procurement" }); + expect(applyProcurementBasisToNode(bare, "complete")).toBe(bare); + }); +}); + +describe("applyProcurementBasisToStep", () => { + it("swaps headline + parks first-receipt in complete_timing for the complete basis", () => { + const out = applyProcurementBasisToStep(procurementStep(), "complete"); + // Headline is now full receipt... + expect(out.stats.median).toBe(25.5); + expect(out.observations.map((observation) => observation.value)).toEqual([ + 24, 26, 25, 27, + ]); + // ...and the secondary cell now carries the first-receipt series. + expect(out.complete_timing?.label).toBe("First receipt"); + expect(out.complete_timing?.stats.median).toBe(9.5); + }); + + it("is a no-op for the first-receipt basis", () => { + const step = procurementStep(); + expect(applyProcurementBasisToStep(step, "first")).toBe(step); + }); +}); + +describe("filterGraphNodeByDateRange with basis", () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-06-15T00:00:00Z")); + }); + afterEach(() => vi.useRealTimers()); + + it("windows the full-receipt series when basis is complete", () => { + // 3m cutoff = 2026-04; keep months >= 2026-04 of the complete series. + const out = filterGraphNodeByDateRange( + procurementNode(), + "3m", + true, + "complete", + ); + expect(out.observations?.map((observation) => observation.value)).toEqual([ + 27, + ]); + expect(out.stats.median).toBe(27); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/procurement-observations.ts b/apps/hash-frontend/src/pages/supply-chain/shared/procurement-observations.ts new file mode 100644 index 00000000000..e1cc6d71606 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/procurement-observations.ts @@ -0,0 +1,116 @@ +import type { ProcurementBasis } from "./procurement-basis-context"; +import type { Observation, ProcurementNodeObservation } from "./types"; + +type DetailRow = Record; + +function isIsoDate(value: unknown): value is string { + return typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value); +} + +function daysBetween(start: string, end: string): number | null { + const startMs = Date.parse(`${start}T00:00:00Z`); + const endMs = Date.parse(`${end}T00:00:00Z`); + if (!Number.isFinite(startMs) || !Number.isFinite(endMs)) { + return null; + } + return Math.round((endMs - startMs) / 86_400_000); +} + +export function isProcurementNodeObservation( + value: unknown, +): value is ProcurementNodeObservation { + if (!value || typeof value !== "object") { + return false; + } + const row = value as Record; + return ( + isIsoDate(row.first_receipt_date) && + typeof row.first_receipt_value === "number" && + isIsoDate(row.last_receipt_date) && + typeof row.last_receipt_value === "number" + ); +} + +export function procurementNodeObservationsForBasis( + observations: ProcurementNodeObservation[], + basis: ProcurementBasis, +): Observation[] { + const isComplete = basis === "complete"; + return observations.map((observation) => ({ + date: isComplete + ? observation.last_receipt_date + : observation.first_receipt_date, + value: isComplete + ? observation.last_receipt_value + : observation.first_receipt_value, + })); +} + +export function deriveProcurementTimingFromRows(rows: DetailRow[]): { + first: Observation[]; + complete: Observation[]; +} | null { + const byPo = new Map(); + for (const row of rows) { + const po = row.po_number; + if (typeof po !== "string" && typeof po !== "number") { + continue; + } + const key = String(po); + const group = byPo.get(key); + if (group) { + group.push(row); + } else { + byPo.set(key, [row]); + } + } + + const first: Observation[] = []; + const complete: Observation[] = []; + + for (const group of byPo.values()) { + const poDate = group.map((row) => row.po_date).find(isIsoDate); + if (!poDate) { + continue; + } + + const firstDates = group + .map((row) => row.first_gr_date) + .filter(isIsoDate) + .sort(); + const lastDates = group + .map((row) => row.last_gr_date) + .filter(isIsoDate) + .sort(); + const firstDate = firstDates[0]; + const lastDate = lastDates[lastDates.length - 1]; + if (!firstDate || !lastDate) { + continue; + } + + const firstValue = daysBetween(poDate, firstDate); + const lastValue = daysBetween(poDate, lastDate); + if ( + firstValue == null || + lastValue == null || + firstValue < 0 || + lastValue < 0 + ) { + continue; + } + + first.push({ date: firstDate, value: firstValue }); + complete.push({ date: lastDate, value: lastValue }); + } + + if (first.length === 0 || complete.length === 0) { + return null; + } + first.sort((left, right) => + left.date < right.date ? -1 : left.date > right.date ? 1 : 0, + ); + complete.sort((left, right) => + left.date < right.date ? -1 : left.date > right.date ? 1 : 0, + ); + return { first, complete }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/range-filter.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/range-filter.test.ts new file mode 100644 index 00000000000..de70be12f61 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/range-filter.test.ts @@ -0,0 +1,89 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { + makeNode, + obs, + stepFrom, + timingSeriesFrom, +} from "./observation-fixtures"; +import { + filterGraphNodeByDateRange, + filterStepByDateRange, +} from "./range-filter"; + +describe("filterStepByDateRange", () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-06-15T00:00:00Z")); + }); + afterEach(() => vi.useRealTimers()); + + const tightStep = () => + stepFrom([ + obs("2026-01", 10), + obs("2026-02", 12), + obs("2026-03", 11), + obs("2026-04", 13), + ]); + + it("windows observations to the cutoff and recomputes stats", () => { + // now=2026-06 -> 3m cutoff = 2026-04; keep months >= 2026-04. + const out = filterStepByDateRange(tightStep(), "3m", true); + expect(out.observations.map((observation) => observation.value)).toEqual([ + 13, + ]); + expect(out.durations).toEqual([13]); + expect(out.stats.n).toBe(1); + expect(out.stats.median).toBe(13); + }); + + it("keeps the full series for the 12m window", () => { + const out = filterStepByDateRange(tightStep(), "12m", true); + expect(out.observations.map((observation) => observation.value)).toEqual([ + 10, 12, 11, 13, + ]); + }); + + it("windows the secondary complete_timing series to the cutoff too", () => { + const step = tightStep(); + step.complete_timing = timingSeriesFrom([ + obs("2026-01", 20), + obs("2026-02", 22), + obs("2026-03", 24), + obs("2026-04", 26), + ]); + // now=2026-06 -> 3m cutoff = 2026-04; keep months >= 2026-04. + const out = filterStepByDateRange(step, "3m", true); + expect( + out.complete_timing?.observations.map((observation) => observation.value), + ).toEqual([26]); + expect(out.complete_timing?.stats.n).toBe(1); + expect(out.complete_timing?.stats.median).toBe(26); + }); +}); + +describe("filterGraphNodeByDateRange", () => { + beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(new Date("2026-06-15T00:00:00Z")); + }); + afterEach(() => vi.useRealTimers()); + + it("returns the full series for the 12m window", () => { + const out = filterGraphNodeByDateRange(makeNode(), "12m", true); + expect(out.observations?.map((observation) => observation.value)).toEqual([ + 10, 12, 11, 13, + ]); + }); + + it("windows observations + monthly to the cutoff and recomputes stats", () => { + // now=2026-06 -> 3m cutoff = 2026-04; keep months >= 2026-04. + const out = filterGraphNodeByDateRange(makeNode(), "3m", true); + expect(out.observations?.map((observation) => observation.value)).toEqual([ + 13, + ]); + expect(out.monthly?.map((month) => month.month)).toEqual(["2026-04"]); + expect(out.stats.n).toBe(1); + expect(out.stats.median).toBe(13); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/range-filter.ts b/apps/hash-frontend/src/pages/supply-chain/shared/range-filter.ts new file mode 100644 index 00000000000..4c4ce5e3f32 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/range-filter.ts @@ -0,0 +1,496 @@ +import { + applyOutlierSelectionToNode, + applyOutlierSelectionToStep, +} from "./outlier-selection"; +import { procurementNodeObservationsForBasis } from "./procurement-observations"; +import { computeStats, percentileOf, round } from "./stats"; +import { cutoffForRange, type TimeRange } from "./time-range"; + +import type { ProcurementBasis } from "./procurement-basis-context"; +import type { + StepDetail, + GraphNode, + Observation, + MonthlyBucket, + StepStats, + YieldData, + ConsumptionData, + ComponentConsumption, + YieldSummary, + ConsumptionSummary, + TimingSeries, +} from "./types"; + +function pctExceeding( + values: number[], + threshold: number | null, +): number | null { + if (threshold == null || values.length === 0) { + return null; + } + return round( + (100 * values.filter((value) => value > threshold).length) / values.length, + ); +} + +function buildMonthlyFromObservations(obs: Observation[]): MonthlyBucket[] { + const byMonth = new Map(); + for (const observation of obs) { + const month = observation.date.slice(0, 7); + const arr = byMonth.get(month); + if (arr) { + arr.push(observation.value); + } else { + byMonth.set(month, [observation.value]); + } + } + return [...byMonth.keys()].sort().map((month) => { + const sorted = [...(byMonth.get(month) ?? [])].sort( + (left, right) => left - right, + ); + return { + month, + mean: round( + sorted.reduce((left, right) => left + right, 0) / sorted.length, + ), + median: round(percentileOf(sorted, 50)), + n: sorted.length, + }; + }); +} + +function filterObservationsByCutoff( + obs: Observation[], + monthly: MonthlyBucket[], + cutoff: string, +): { + observations: Observation[]; + values: number[]; + monthly: MonthlyBucket[]; + stats: StepStats; +} { + const filtered = obs.filter( + (observation) => observation.date.slice(0, 7) >= cutoff, + ); + const values = filtered.map((observation) => observation.value); + return { + observations: filtered, + values, + monthly: monthly.filter((month) => month.month >= cutoff), + stats: computeStats(values), + }; +} + +function filterYieldData(yd: YieldData, cutoff: string): YieldData { + const row = filterObservationsByCutoff(yd.observations, yd.monthly, cutoff); + return { + ...yd, + values: row.values, + observations: row.observations, + monthly: row.monthly, + stats: row.stats, + }; +} + +function filterComponentReconciliationCounts( + comp: ComponentConsumption, + cutoff: string, +): Partial { + const rows = comp.detail_rows?.rows ?? []; + if (!rows.length) { + return {}; + } + + const windowRows = rows.filter((row) => { + const rawDate = row.finish_date; + return typeof rawDate === "string" && rawDate.slice(0, 7) >= cutoff; + }); + const orderIds = new Set(); + const planned = new Set(); + const consumed = new Set(); + const offBom = new Set(); + const plannedNotConsumed = new Set(); + const unplanned = new Set(); + + for (const row of windowRows) { + const aufnr = + typeof row.aufnr === "string" || typeof row.aufnr === "number" + ? String(row.aufnr) + : null; + if (!aufnr) { + continue; + } + orderIds.add(aufnr); + const status = String(row.status ?? ""); + if (row.planned_qty != null) { + planned.add(aufnr); + } + if (row.actual_qty != null) { + consumed.add(aufnr); + } + if (status === "off-BOM") { + offBom.add(aufnr); + } + if (status === "planned, not consumed") { + plannedNotConsumed.add(aufnr); + } + if (status === "unplanned") { + unplanned.add(aufnr); + } + } + + return { + n_reconciliation_events: orderIds.size, + n_orders_planned: planned.size, + n_orders_consumed: consumed.size, + n_orders_off_bom: offBom.size, + n_orders_planned_not_consumed: plannedNotConsumed.size, + n_orders_unplanned: unplanned.size, + }; +} + +function filterComponentConsumption( + comp: ComponentConsumption, + cutoff: string, +): ComponentConsumption { + const row = filterObservationsByCutoff( + comp.observations, + comp.monthly, + cutoff, + ); + return { + ...comp, + ...filterComponentReconciliationCounts(comp, cutoff), + values: row.values, + observations: row.observations, + monthly: row.monthly, + stats: row.stats, + }; +} + +function weightedVarianceFromObservations(obs: Observation[]): number | null { + const totals = obs.reduce( + (acc, observation) => { + acc.actual += observation.actual_qty ?? 0; + acc.expected += observation.expected_qty ?? 0; + return acc; + }, + { actual: 0, expected: 0 }, + ); + if (totals.expected <= 0) { + return null; + } + return round(((totals.actual - totals.expected) / totals.expected) * 100); +} + +function filterConsumptionData( + cd: ConsumptionData, + cutoff: string, +): ConsumptionData { + const components = cd.components.map((column) => + filterComponentConsumption(column, cutoff), + ); + const aggObs = cd.aggregate.observations.filter( + (observation) => observation.date.slice(0, 7) >= cutoff, + ); + const aggValues = aggObs.map((observation) => observation.value); + const monthly = cd.aggregate.monthly.filter((month) => month.month >= cutoff); + + // Window the raw per-order rows so the off-BOM / substitution callouts are + // window-aware (matching how weighted_variance_pct is recomputed above). The + // off_bom_components list stays as the backend all-time reference because the + // per-component series is matched-only and would under-count unplanned rows. + const allOrders = cd.aggregate.orders; + let windowed: Partial = {}; + if (allOrders) { + const windowOrders = allOrders.filter( + (observation) => observation.date.slice(0, 7) >= cutoff, + ); + let nOffBom = 0; + let nPnc = 0; + let nUnplanned = 0; + let nSub = 0; + for (const observation of windowOrders) { + if (observation.off_bom) { + nOffBom += 1; + } + if (observation.planned_not_consumed) { + nPnc += 1; + } + if (observation.unplanned) { + nUnplanned += 1; + } + if (observation.substitution) { + nSub += 1; + } + } + windowed = { + orders: windowOrders, + n_orders: windowOrders.length, + n_orders_off_bom: nOffBom, + n_orders_planned_not_consumed: nPnc, + n_orders_unplanned: nUnplanned, + n_orders_substitution: nSub, + }; + } + + return { + components, + aggregate: { + ...cd.aggregate, + values: aggValues, + observations: aggObs, + monthly, + stats: computeStats(aggValues), + weighted_variance_pct: weightedVarianceFromObservations(aggObs), + ...windowed, + }, + }; +} + +/** + * Procurement step counterpart of {@link applyProcurementBasisToNode}. When the + * basis is "complete", promotes the full-receipt series to the headline + * (durations/observations/monthly/stats) and parks the first-receipt series in + * `complete_timing` so the slideover's secondary cell shows the *other* basis. + * No-op for any other basis / non-procurement step / step without + * `complete_timing`. + */ +export function applyProcurementBasisToStep( + step: StepDetail, + basis: ProcurementBasis, +): StepDetail { + if ( + basis !== "complete" || + step.type !== "procurement" || + !step.complete_timing + ) { + return step; + } + const comp = step.complete_timing; + const first: TimingSeries = { + label: "First receipt", + observations: step.observations, + monthly: step.monthly, + stats: step.stats, + }; + const values = comp.observations.map((observation) => observation.value); + return { + ...step, + durations: values, + observations: comp.observations, + monthly: comp.monthly, + stats: comp.stats, + pct_exceeding_plan: pctExceeding(values, step.plan), + complete_timing: first, + }; +} + +/** Outlier selection followed by date-range windowing (for raw, unprocessed steps). */ + +/** + * Window an (already outlier-selected) step to a `TimeRange`, recomputing + * stats/cost/yield/consumption for the window. Does not re-run outlier + * selection, so callers that pre-applied it are not double-processed. + */ + +function filterTimingSeries(ts: TimingSeries, cutoff: string): TimingSeries { + const { observations, monthly, stats } = filterObservationsByCutoff( + ts.observations, + ts.monthly, + cutoff, + ); + return { ...ts, observations, monthly, stats }; +} + +/** + * Recompute a production node's `yield_summary` from its windowed (and, when the + * caller pre-applied it, outlier-filtered) yield series. Returns undefined when + * the node carries no series (e.g. non-production nodes), so the caller leaves + * the node's summary untouched. Empty windows collapse the summary to null so + * the badge hides. + */ export function windowStepToRange( + selectedStep: StepDetail, + range: TimeRange, +): StepDetail { + const cutoff = cutoffForRange(range); + const hasObservations = selectedStep.observations.length > 0; + if (!hasObservations) { + return selectedStep; + } + const filtered = selectedStep.observations.filter( + (observation: Observation) => observation.date.slice(0, 7) >= cutoff, + ); + const values = filtered.map((observation: Observation) => observation.value); + const stats = computeStats(values); + const filteredMonthly: MonthlyBucket[] = selectedStep.monthly.filter( + (month) => month.month >= cutoff, + ); + const filteredYield = selectedStep.yield_data + ? filterYieldData(selectedStep.yield_data, cutoff) + : selectedStep.yield_data; + const filteredConsumption = selectedStep.consumption_data + ? filterConsumptionData(selectedStep.consumption_data, cutoff) + : selectedStep.consumption_data; + const filteredCompleteTiming = selectedStep.complete_timing + ? filterTimingSeries(selectedStep.complete_timing, cutoff) + : selectedStep.complete_timing; + return { + ...selectedStep, + durations: values, + observations: filtered, + monthly: filteredMonthly, + stats, + cost: selectedStep.cost, + pct_exceeding_plan: pctExceeding(values, selectedStep.plan), + yield_data: filteredYield, + consumption_data: filteredConsumption, + complete_timing: filteredCompleteTiming, + }; +} +/** Window a secondary {@link TimingSeries} to a cutoff month, recomputing stats. */ export function filterStepByDateRange( + step: StepDetail, + range: TimeRange, + excludeOutliers = true, + basis: ProcurementBasis = "first", +): StepDetail { + return windowStepToRange( + applyOutlierSelectionToStep( + applyProcurementBasisToStep(step, basis), + excludeOutliers, + ), + range, + ); +} +function recomputeYieldSummary( + series: GraphNode["yield_series"], + cutoff: string, +): YieldSummary | null | undefined { + if (!series) { + return undefined; + } + const obs = series.observations.filter( + (observation) => observation.date.slice(0, 7) >= cutoff, + ); + if (obs.length === 0) { + return null; + } + const stats = computeStats(obs.map((observation) => observation.value)); + return { + median: stats.median ?? 0, + mean: stats.mean ?? 0, + reference: series.reference, + n: stats.n, + }; +} + +/** Consumption counterpart of {@link recomputeYieldSummary}. */ +function recomputeConsumptionSummary( + series: GraphNode["consumption_series"], + cutoff: string, +): ConsumptionSummary | null | undefined { + if (!series) { + return undefined; + } + const obs = series.observations.filter( + (observation) => observation.date.slice(0, 7) >= cutoff, + ); + if (obs.length === 0) { + return null; + } + const stats = computeStats(obs.map((observation) => observation.value)); + return { + median_variance: stats.median ?? 0, + mean_variance: stats.mean ?? 0, + weighted_variance: weightedVarianceFromObservations(obs), + n_components: series.n_components, + n: stats.n, + }; +} + +/** + * Select a procurement node's headline timing basis from the combined + * first/last receipt observations. Applied before outlier selection + windowing + * so the entire downstream pipeline operates on the selected basis. + */ +export function applyProcurementBasisToNode( + node: GraphNode, + basis: ProcurementBasis, +): GraphNode { + if (node.type !== "procurement" || !node.procurement_observations) { + return node; + } + const observations = procurementNodeObservationsForBasis( + node.procurement_observations, + basis, + ); + const values = observations.map((observation) => observation.value); + return { + ...node, + observations, + monthly: buildMonthlyFromObservations(observations), + stats: computeStats(values), + pct_exceeding_plan: pctExceeding(values, node.plan), + }; +} + +/** Outlier selection followed by date-range windowing (for raw, unprocessed nodes). */ + +/** + * Window an (already outlier-selected) node to a `TimeRange`. Does not re-run + * outlier selection, so pre-applied nodes are not double-processed. + */ +export function windowGraphNodeToRange( + selectedNode: GraphNode, + range: TimeRange, +): GraphNode { + const cutoff = cutoffForRange(range); + const obs = selectedNode.observations ?? []; + if (obs.length === 0) { + return selectedNode; + } + + const filtered = obs.filter( + (observation: Observation) => observation.date.slice(0, 7) >= cutoff, + ); + const values = filtered.map((observation: Observation) => observation.value); + const stats = computeStats(values); + const filteredMonthly = (selectedNode.monthly ?? []).filter( + (month) => month.month >= cutoff, + ); + + // Recompute the R:/C: badge summaries from the windowed series when present; + // `undefined` means "no series shipped" -> keep the node's existing summary. + const yieldSummary = recomputeYieldSummary(selectedNode.yield_series, cutoff); + const consumptionSummary = recomputeConsumptionSummary( + selectedNode.consumption_series, + cutoff, + ); + + return { + ...selectedNode, + stats, + observations: filtered, + monthly: filteredMonthly, + cost: selectedNode.cost, + pct_exceeding_plan: pctExceeding(values, selectedNode.plan), + ...(yieldSummary !== undefined ? { yield_summary: yieldSummary } : {}), + ...(consumptionSummary !== undefined + ? { consumption_summary: consumptionSummary } + : {}), + }; +} +export function filterGraphNodeByDateRange( + node: GraphNode, + range: TimeRange, + excludeOutliers = true, + basis: ProcurementBasis = "first", +): GraphNode { + return windowGraphNodeToRange( + applyOutlierSelectionToNode( + applyProcurementBasisToNode(node, basis), + excludeOutliers, + ), + range, + ); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/records-derive.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/records-derive.test.ts new file mode 100644 index 00000000000..737474ebb69 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/records-derive.test.ts @@ -0,0 +1,257 @@ +import { describe, expect, it } from "vitest"; + +import { deriveTimingFromRecords, ensureStepStats } from "./normalize-contract"; + +import type { DetailRows, StepDetail } from "./types"; + +const detailRows: DetailRows = { + columns: [ + { + key: "consumption_date", + source_field: "BUDAT", + source_table: "MKPF", + label: "Consumption Date", + }, + { + key: "dwell_days", + source_field: null, + source_table: null, + label: "Dwell Days", + }, + ], + + rows: [ + { consumption_date: "2026-01-10", dwell_days: 10 }, + { consumption_date: "2026-01-20", dwell_days: 20 }, + { consumption_date: "2026-02-05", dwell_days: 30 }, + ], +}; + +function recordsOnlyStep(overrides: Partial = {}): StepDetail { + return { + id: "s1", + label: "Step", + type: "raw_material_dwell", + durations: [], + observations: [], + monthly: [], + stats: { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, + }, + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: null, + detail_rows: detailRows, + ref_date_col: "consumption_date", + value_col: "dwell_days", + ...overrides, + }; +} + +describe("deriveTimingFromRecords", () => { + it("rehydrates observations/durations/monthly/stats from detail_rows", () => { + const derived = deriveTimingFromRecords(recordsOnlyStep()); + expect( + derived.observations.map((observation) => observation.value), + ).toEqual([10, 20, 30]); + expect(derived.durations).toEqual([10, 20, 30]); + expect(derived.stats.n).toBe(3); + expect(derived.stats.median).toBe(20); + // Two calendar months: 2026-01 (10,20) and 2026-02 (30). + expect(derived.monthly.map((month) => month.month)).toEqual([ + "2026-01", + "2026-02", + ]); + const january = derived.monthly[0]; + const february = derived.monthly[1]; + expect(january).toBeDefined(); + expect(february).toBeDefined(); + expect(january!.n).toBe(2); + expect(february!.median).toBe(30); + }); + + it("is a strict no-op when observations are already present", () => { + const step = recordsOnlyStep({ + observations: [{ date: "2026-03-01", value: 99 }], + }); + const derived = deriveTimingFromRecords(step); + expect(derived.observations).toEqual([{ date: "2026-03-01", value: 99 }]); + expect(derived).toBe(step); + }); + + it("is a no-op without value_col", () => { + const step = recordsOnlyStep({ value_col: null }); + expect(deriveTimingFromRecords(step)).toBe(step); + }); + + it("ensureStepStats derives then fills stats for a records-only payload", () => { + const out = ensureStepStats(recordsOnlyStep()); + expect(out.stats.n).toBe(3); + expect(out.observations).toHaveLength(3); + }); + + it.each([ + { + type: "transit" as const, + dateCol: "arrival_date", + valueCol: "transit_days", + rows: [ + { arrival_date: "2026-01-15", transit_days: 31 }, + { arrival_date: "2026-01-18", transit_days: 9 }, + ], + }, + { + type: "qa_hold" as const, + dateCol: "qa_release_date", + valueCol: "hold_days", + rows: [ + { qa_release_date: "2026-03-02", hold_days: 4 }, + { qa_release_date: "2026-04-12", hold_days: 8 }, + ], + }, + { + type: "production" as const, + dateCol: "finish_date", + valueCol: "production_days", + rows: [ + { finish_date: "2026-05-01", production_days: 3 }, + { finish_date: "2026-05-06", production_days: 7 }, + ], + }, + { + type: "destination_dwell" as const, + dateCol: "outbound_date", + valueCol: "dwell_days", + rows: [ + { outbound_date: "2026-06-01", dwell_days: 15 }, + { outbound_date: "2026-06-21", dwell_days: 25 }, + ], + }, + ])( + "derives representative $type records-only timing payloads", + ({ type, dateCol, valueCol, rows }) => { + const indexedRows = rows as Array>; + const step = recordsOnlyStep({ + type, + detail_rows: { + columns: [ + { + key: dateCol, + source_field: null, + source_table: null, + label: dateCol, + }, + { + key: valueCol, + source_field: null, + source_table: null, + label: valueCol, + }, + ], + + rows: indexedRows, + }, + ref_date_col: dateCol, + value_col: valueCol, + }); + + const out = ensureStepStats(step); + expect(out.observations).toEqual( + indexedRows.map((row) => ({ + date: row[dateCol] as string, + value: row[valueCol] as number, + })), + ); + expect(out.stats.n).toBe(rows.length); + expect(out.monthly.length).toBeGreaterThan(0); + }, + ); + + it("derives procurement timing as one first/full observation per PO", () => { + const step = recordsOnlyStep({ + type: "procurement", + detail_rows: { + columns: [ + { + key: "po_number", + source_field: null, + source_table: null, + label: "PO Number", + }, + { + key: "po_date", + source_field: null, + source_table: null, + label: "PO Date", + }, + { + key: "first_gr_date", + source_field: null, + source_table: null, + label: "First GR Date", + }, + { + key: "last_gr_date", + source_field: null, + source_table: null, + label: "Last GR Date", + }, + { + key: "lead_time_days", + source_field: null, + source_table: null, + label: "First Receipt (days)", + }, + ], + + rows: [ + { + po_number: "PO-A", + po_date: "2026-01-01", + first_gr_date: "2026-01-11", + last_gr_date: "2026-01-11", + lead_time_days: 10, + }, + { + po_number: "PO-A", + po_date: "2026-01-01", + first_gr_date: "2026-01-31", + last_gr_date: "2026-01-31", + lead_time_days: 30, + }, + { + po_number: "PO-B", + po_date: "2026-02-01", + first_gr_date: "2026-02-21", + last_gr_date: "2026-03-18", + lead_time_days: 20, + }, + ], + }, + ref_date_col: "first_gr_date", + value_col: "lead_time_days", + }); + + const out = ensureStepStats(step); + expect(out.observations).toEqual([ + { date: "2026-01-11", value: 10 }, + { date: "2026-02-21", value: 20 }, + ]); + expect(out.complete_timing?.observations).toEqual([ + { date: "2026-01-31", value: 30 }, + { date: "2026-03-18", value: 45 }, + ]); + expect(out.stats.n).toBe(2); + expect(out.complete_timing?.stats.n).toBe(2); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/registry-context.ts b/apps/hash-frontend/src/pages/supply-chain/shared/registry-context.ts new file mode 100644 index 00000000000..d31825c524a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/registry-context.ts @@ -0,0 +1,25 @@ +import { createContext, useContext } from "react"; + +import type { SiteRef } from "./data"; +import type { Product } from "./types"; + +/** + * The product + site registry, loaded once by `SupplyChainDataShell` and shared with every + * page via context. Mirrors the SPA's single `AppLayout` bootstrap (products and + * sites were fetched once at app start) now that each route is its own page. + */ +export interface Registry { + products: Product[]; + sites: SiteRef[]; + demoActive: boolean; +} + +export const RegistryContext = createContext({ + products: [], + sites: [], + demoActive: false, +}); + +export function useRegistry(): Registry { + return useContext(RegistryContext); +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/scope-context.ts b/apps/hash-frontend/src/pages/supply-chain/shared/scope-context.ts new file mode 100644 index 00000000000..32b76de5d7a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/scope-context.ts @@ -0,0 +1,20 @@ +import { createContext, useContext } from "react"; + +/** + * The active data scope. Supply-chain views use this to scope analysis queries, + * status reports, and user preferences to the resolved HASH web. + * + * Following the codebase convention (see `registry-context`/`cost`), the context + * + hook live here and `SupplyChainDataShell` renders `ScopeContext.Provider` inline. + */ +export const LOCAL_SCOPE = "local"; + +export interface Scope { + scope: string; +} + +export const ScopeContext = createContext({ scope: LOCAL_SCOPE }); + +export function useScope(): string { + return useContext(ScopeContext).scope; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/scope-select.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/scope-select.tsx new file mode 100644 index 00000000000..74c52120e85 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/scope-select.tsx @@ -0,0 +1,65 @@ +import { useRouter } from "next/router"; +import { useCallback } from "react"; + +import { useRegistry } from "./registry-context"; +import { SearchableSelect } from "./searchable-select"; + +/** + * Product/site picker rendered as the page title (display-sized dropdown). Reads + * the registry + active scope to show the selected label, and navigates on change. + */ +export const ScopeSelect = ({ + productId: productIdProp, + siteId: siteIdProp, +}: { productId?: string; siteId?: string } = {}) => { + const router = useRouter(); + const { products, sites } = useRegistry(); + + const query = router.query as Record; + const isSiteScope = router.pathname.startsWith("/supply-chain/site/"); + const productId = + productIdProp ?? query.productId ?? query["product-id"] ?? ""; + const siteId = siteIdProp ?? query.siteId ?? query["site-id"] ?? ""; + const scopeValue = isSiteScope ? `site:${siteId}` : productId; + + const handleScopeChange = useCallback( + (val: string) => { + if (val.startsWith("site:")) { + void router.push(`/supply-chain/site/${val.replace("site:", "")}`); + } else { + void router.push(`/supply-chain/product/${val}`); + } + }, + [router], + ); + + const scopeGroups = [ + ...(sites.length > 0 + ? [ + { + label: "Sites", + options: sites.map((step) => ({ + value: `site:${step.slug}`, + label: step.name, + })), + }, + ] + : []), + { + label: "Products", + options: products.map((product) => ({ + value: product.id, + label: product.name, + })), + }, + ]; + + return ( + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/searchable-select.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/searchable-select.tsx new file mode 100644 index 00000000000..af3dcd5eb02 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/searchable-select.tsx @@ -0,0 +1,231 @@ +import { Combobox, createListCollection, Portal } from "@ark-ui/react"; +import { useMemo, useState } from "react"; + +import { Icon, usePortalContainerRef } from "@hashintel/ds-components"; +import { css } from "@hashintel/ds-helpers/css"; + +/** + * Local grouped, searchable select built on `@ark-ui/react/combobox` and styled + * with ds-helpers `css()` + design-system tokens. The popover portals into the + * supply-chain layout's token scope. + */ +export interface OptionGroup { + label: string; + options: { value: string; label: string }[]; +} + +interface SearchableSelectProps { + value: string; + onChange: (value: string) => void; + groups: OptionGroup[]; + className?: string; + /** `sm` is the compact toolbar pill; `lg` renders as a display-sized page title. */ + size?: "sm" | "lg"; +} + +const triggerStyles = css({ + display: "inline-flex", + alignItems: "center", + gap: "1", + height: "7", + maxW: "[260px]", + paddingX: "2", + textStyle: "xs", + color: "fg.body", + bg: "bgSolid.min", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "md", + cursor: "pointer", + transition: "colors", + _hover: { borderColor: "bd.solid" }, +}); + +const inputStyles = css({ + flex: "1", + height: "7", + paddingX: "2", + textStyle: "xs", + color: "fg.body", + bg: "[transparent]", + outline: "none", + _placeholder: { color: "fg.subtle" }, +}); + +const triggerLgStyles = css({ + display: "inline-flex", + alignItems: "center", + gap: "2", + maxW: "[480px]", + ml: "[-6px]", + paddingX: "1.5", + paddingY: "0.5", + bg: "[transparent]", + borderWidth: "0", + cursor: "pointer", + _hover: { bg: "bg.subtle" }, +}); + +const inputLgStyles = css({ + fontFamily: "display", + textStyle: "2xl", + fontWeight: "medium", + color: "fg.heading", + lineHeight: "[30px]", + bg: "[transparent]", + outline: "none", + minW: "0", +}); + +const contentStyles = css({ + display: "flex", + flexDirection: "column", + width: "64", + maxH: "[300px]", + overflowY: "auto", + padding: "1", + bg: "bgSolid.min", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "lg", + boxShadow: "lg", + zIndex: "dropdown", +}); + +const groupLabelStyles = css({ + paddingX: "3", + paddingTop: "2", + paddingBottom: "1", + textStyle: "xxs", + fontWeight: "medium", + textTransform: "uppercase", + letterSpacing: "wider", + color: "fg.subtle", +}); + +const itemStyles = css({ + paddingX: "3", + paddingY: "1.5", + textStyle: "xs", + color: "fg.body", + borderRadius: "sm", + cursor: "pointer", + "&[data-highlighted]": { bg: "bg.subtle" }, + "&[data-state=checked]": { color: "fg.heading", fontWeight: "medium" }, +}); + +const emptyStyles = css({ + paddingX: "3", + paddingY: "2", + textStyle: "xs", + color: "fg.subtle", +}); + +export const SearchableSelect = ({ + value, + onChange, + groups, + className, + size = "sm", +}: SearchableSelectProps) => { + const allOptions = useMemo( + () => groups.flatMap((group) => group.options), + [groups], + ); + const selectedLabel = + allOptions.find((observation) => observation.value === value)?.label ?? + value; + + const [query, setQuery] = useState(""); + + const filteredGroups = useMemo(() => { + const query2 = query.trim().toLowerCase(); + if (!query2) { + return groups; + } + return groups + .map((group) => ({ + ...group, + options: group.options.filter((observation) => + observation.label.toLowerCase().includes(query2), + ), + })) + .filter((group) => group.options.length > 0); + }, [groups, query]); + + const collection = useMemo( + () => + createListCollection({ + items: filteredGroups.flatMap((group) => group.options), + itemToValue: (item) => item.value, + itemToString: (item) => item.label, + }), + [filteredGroups], + ); + + const portalRef = usePortalContainerRef(); + + return ( + { + const next = details.value[0]; + if (next !== undefined) { + onChange(next); + } + }} + onInputValueChange={(details) => setQuery(details.inputValue)} + onOpenChange={(details) => { + if (!details.open) { + setQuery(""); + } + }} + selectionBehavior="replace" + placeholder={selectedLabel} + className={className} + > + + + + + + + + + + {filteredGroups.length === 0 ? ( + + No results + + ) : ( + filteredGroups.map((group) => ( + + + {group.label} + + {group.options.map((option) => ( + + {option.label} + + ))} + + )) + )} + + + + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/segmented-control.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/segmented-control.tsx new file mode 100644 index 00000000000..c0d14984154 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/segmented-control.tsx @@ -0,0 +1,81 @@ +import { css, cx } from "@hashintel/ds-helpers/css"; + +// DELIBERATELY local. The ds `SegmentedControl` renders a frosted-glass backdrop +// (`backdrop-filter: blur`, white/translucent fills, hardcoded rgba borders) and +// an oversized item box (`paddingX:5 paddingY:4`, `fontSize:sm`) that neither +// matches this app's flat neutral surfaces nor fits the `xs` toolbar density. +// We keep this control but drive every value from ds tokens/`textStyle` so it +// stays visually consistent. + +interface SegmentedControlProps { + value: T; + onChange: (value: T) => void; + options: { value: T; label: string }[]; + className?: string; +} + +const group = css({ + display: "inline-flex", + alignItems: "center", + borderRadius: "md", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + bg: "bg.surface", + p: "0.5", + gap: "0.5", +}); + +const button = css({ + px: "3", + py: "1", + textStyle: "xs", + // Pin a tight leading: the `xs` textStyle's 1.6em line-height otherwise + // inflates the control height well beyond its padding. + lineHeight: "none", + fontWeight: "medium", + // Inner radius one step below the group's `md` so the active pill nests + // cleanly inside the 0.5 padding; token-driven (no arbitrary px). + borderRadius: "sm", + transition: "colors", + whiteSpace: "nowrap", + cursor: "pointer", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "[transparent]", +}); +const buttonActive = css({ + bg: "bgSolid.min", + borderColor: "bd.subtle", + color: "fg.heading", + boxShadow: "sm", +}); +const buttonInactive = css({ + color: "fg.subtle", + _hover: { color: "fg.muted" }, +}); + +export const SegmentedControl = ({ + value, + onChange, + options, + className, +}: SegmentedControlProps) => { + return ( +
    + {options.map((opt) => ( + + ))} +
    + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.test.ts new file mode 100644 index 00000000000..d41bcc5321b --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.test.ts @@ -0,0 +1,283 @@ +import { describe, expect, it } from "vitest"; + +import { + computeNodePeriodCost, + countBadPlanningParams, + deduplicateNodes, + topDwellCosts, + topPlanningMismatches, +} from "./site-aggregation"; + +import type { + CostData, + GraphData, + GraphNode, + MonthlyBucket, + Product, + SiteData, + SiteNode, + StepStats, +} from "./types"; + +const zeroStats: StepStats = { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, +}; + +function stats(count: number, median: number): StepStats { + return { ...zeroStats, n: count, median, mean: median }; +} + +function cost(unitPrice: number | null): CostData { + return { unit_price: unitPrice, currency: "EUR" }; +} + +function kgDayMonth(month: string, totalKgDays: number): MonthlyBucket { + return { month, mean: null, median: null, n: 1, total_kg_days: totalKgDays }; +} + +function node(overrides: Partial): GraphNode { + return { + id: "n", + label: "Node", + type: "intermediate_dwell", + material: null, + plant: "PL-A", + stats: zeroStats, + plan: null, + plan_note: null, + pct_exceeding_plan: null, + cost: null, + ...overrides, + }; +} + +function siteNode(overrides: Partial): SiteNode { + return { ...node({}), products: [{ id: "p1", name: "P1" }], ...overrides }; +} + +describe("deduplicateNodes", () => { + it("merges shared raw-material nodes across products by material, plant, type, and series", () => { + const shared = node({ + id: "rm", + type: "raw_material_dwell", + material: "MAT-1", + plant: "PL-A", + }); + const productA: Product = { id: "pa", name: "Product A", material: "FG-A" }; + const productB: Product = { id: "pb", name: "Product B", material: "FG-B" }; + const graphA: GraphData = { + product_id: "pa", + product_name: "Product A", + nodes: [ + shared, + node({ id: "prodA", type: "production", material: "FG-A" }), + ], + + edges: [], + pipeline_summary: {}, + }; + const graphB: GraphData = { + product_id: "pb", + product_name: "Product B", + nodes: [ + shared, + node({ id: "prodB", type: "production", material: "FG-B" }), + ], + + edges: [], + pipeline_summary: {}, + }; + const site: SiteData = { + graphs: [ + { product: productA, graph: graphA }, + { product: productB, graph: graphB }, + ], + }; + + const result = deduplicateNodes(site); + const rm = result.find((row) => row.id === "rm"); + expect(rm).toBeDefined(); + expect(rm?.products.map((product) => product.id).sort()).toEqual([ + "pa", + "pb", + ]); + // The two product-specific production nodes stay distinct. + expect(result.filter((row) => row.type === "production")).toHaveLength(2); + }); + + it("merges duplicated intermediate dwell rows used by multiple products", () => { + const monthly = [kgDayMonth("2026-01", 10000)]; + const sharedA = node({ + id: "im-a", + label: "Intermediate Dwell: MN-L Wet Cake", + type: "intermediate_dwell", + material: "MN-L Wet Cake", + plant: "PL-A", + stats: stats(10, 23.5), + cost: cost(100), + monthly, + }); + const sharedB = { ...sharedA, id: "im-b" }; + const productA: Product = { id: "pa", name: "Product A", material: "FG-A" }; + const productB: Product = { id: "pb", name: "Product B", material: "FG-B" }; + const site: SiteData = { + graphs: [ + { + product: productA, + graph: { + product_id: "pa", + product_name: "Product A", + nodes: [sharedA], + edges: [], + pipeline_summary: {}, + }, + }, + { + product: productB, + graph: { + product_id: "pb", + product_name: "Product B", + nodes: [sharedB], + edges: [], + pipeline_summary: {}, + }, + }, + ], + }; + + const result = deduplicateNodes(site); + + expect(result).toHaveLength(1); + const deduplicated = result[0]; + expect(deduplicated).toBeDefined(); + expect(deduplicated!.products.map((product) => product.id).sort()).toEqual([ + "pa", + "pb", + ]); + expect(computeNodePeriodCost(deduplicated!, 0.1, 0.336)).toBeCloseTo( + computeNodePeriodCost({ ...sharedA, products: [productA] }, 0.1, 0.336), + 6, + ); + }); + + it("keeps genuinely different dwell series separate even when material matches", () => { + const base = node({ + id: "im-a", + label: "Intermediate Dwell: Shared Material", + type: "intermediate_dwell", + material: "Shared Material", + plant: "PL-A", + stats: stats(10, 20), + cost: cost(100), + monthly: [kgDayMonth("2026-01", 10000)], + }); + const different = { + ...base, + id: "im-b", + stats: stats(8, 12), + monthly: [kgDayMonth("2026-01", 3000)], + }; + const productA: Product = { id: "pa", name: "Product A", material: "FG-A" }; + const productB: Product = { id: "pb", name: "Product B", material: "FG-B" }; + const site: SiteData = { + graphs: [ + { + product: productA, + graph: { + product_id: "pa", + product_name: "Product A", + nodes: [base], + edges: [], + pipeline_summary: {}, + }, + }, + { + product: productB, + graph: { + product_id: "pb", + product_name: "Product B", + nodes: [different], + edges: [], + pipeline_summary: {}, + }, + }, + ], + }; + + expect(deduplicateNodes(site)).toHaveLength(2); + }); +}); + +describe("computeNodePeriodCost", () => { + it("sums monthly kg-day cost using unit price + params", () => { + const count = siteNode({ + cost: cost(100), + monthly: [kgDayMonth("2026-01", 1000), kgDayMonth("2026-02", 500)], + }); + const wacc = 0.1; + const storage = 0.336; + const rate = 100 * (wacc / 365) + storage / 1000; + expect(computeNodePeriodCost(count, wacc, storage)).toBeCloseTo( + 1500 * rate, + 6, + ); + }); + + it("is zero with no monthly data", () => { + expect( + computeNodePeriodCost(siteNode({ cost: cost(100) }), 0.1, 0.336), + ).toBe(0); + }); +}); + +describe("site rollups", () => { + const dwellBig = siteNode({ + id: "d1", + type: "intermediate_dwell", + stats: stats(10, 30), + cost: cost(100), + monthly: [kgDayMonth("2026-01", 10000)], + }); + const dwellSmall = siteNode({ + id: "d2", + type: "post_qa_ship", + stats: stats(10, 5), + cost: cost(10), + monthly: [kgDayMonth("2026-01", 100)], + }); + + it("ranks dwell nodes by period cost", () => { + const top = topDwellCosts([dwellBig, dwellSmall], 0.1, 0.336, 5); + expect(top.map((threshold) => threshold.id)).toEqual(["d1", "d2"]); + const first = top[0]; + const second = top[1]; + expect(first).toBeDefined(); + expect(second).toBeDefined(); + expect(first!.periodCost).toBeGreaterThan(second!.periodCost); + }); + + it("ranks planning mismatches by deviation vs plan", () => { + const over = siteNode({ id: "o", stats: stats(5, 30), plan: 10 }); // +200% + const under = siteNode({ id: "u", stats: stats(5, 12), plan: 10 }); // +20% + const top = topPlanningMismatches([under, over], 5); + const topMismatch = top[0]; + expect(topMismatch).toBeDefined(); + expect(topMismatch!.id).toBe("o"); + expect(topMismatch!.deviationPct).toBeCloseTo(200, 6); + }); + + it("counts nodes whose median exceeds plan by >20%", () => { + const bad = siteNode({ id: "b", stats: stats(5, 13), plan: 10 }); // 1.3x + const ok = siteNode({ id: "k", stats: stats(5, 11), plan: 10 }); // 1.1x + expect(countBadPlanningParams([bad, ok])).toBe(1); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.ts b/apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.ts new file mode 100644 index 00000000000..5bd04e48b74 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/site-aggregation.ts @@ -0,0 +1,197 @@ +import { DWELL_TYPES } from "./categories"; +import { computePeriodCost } from "./cost"; +import { type BaseMeasure, selectStat } from "./measure-context"; + +import type { + MonthlyBucket, + SiteData, + SiteNode, + GraphNode, + StepStats, +} from "./types"; + +const SHARED_STEP_TYPES = new Set(["raw_material_dwell", "procurement"]); + +function normaliseLabel(label: string): string { + return label.trim().toLowerCase().replace(/\s+/g, " "); +} +function fingerprintValue(value: string | number | null | undefined): string { + if (typeof value === "number") { + return Number.isFinite(value) ? value.toPrecision(12) : "nan"; + } + return value ?? "null"; +} +function costFingerprint( + unitPrice: number | null | undefined, + currency: string | null | undefined, +): string { + return [unitPrice, currency].map(fingerprintValue).join(":"); +} +function monthlyFingerprint(monthly: MonthlyBucket[] | undefined): string { + if (!monthly || monthly.length === 0) { + return "no-monthly"; + } + return monthly + .map((month) => + [month.month, month.n, month.total_kg_days, month.mean, month.median] + .map(fingerprintValue) + .join(":"), + ) + .join(";"); +} +function statsFingerprint(stats: StepStats): string { + return [ + stats.n, + stats.mean, + stats.median, + stats.std, + stats.min, + stats.max, + stats.p25, + stats.p75, + stats.p85, + stats.p95, + ] + .map(fingerprintValue) + .join(","); +} +function dwellSeriesFingerprint(node: GraphNode): string { + return [ + statsFingerprint(node.stats), + monthlyFingerprint(node.monthly), + costFingerprint(node.cost?.unit_price, node.cost?.currency), + ].join("~"); +} +function dwellDedupKey(node: GraphNode, productId: string): string { + const series = dwellSeriesFingerprint(node); + if (node.material) { + return ["dwell", node.plant, node.type, node.material, series].join("|"); + } + return [ + "dwell", + node.plant, + node.type, + normaliseLabel(node.label), + series || productId, + ].join("|"); +} +function dedupKey(node: GraphNode, productId: string): string { + if (DWELL_TYPES.includes(node.type)) { + return dwellDedupKey(node, productId); + } + if (SHARED_STEP_TYPES.has(node.type) && node.material) { + return ["shared", node.material, node.plant, node.type].join("|"); + } + return ["product", productId, node.id, node.plant, node.type].join("|"); +} + +export function deduplicateNodes(siteData: SiteData): SiteNode[] { + const grouped = new Map< + string, + { node: GraphNode; products: Array<{ id: string; name: string }> } + >(); + + for (const { product, graph } of siteData.graphs) { + for (const node of graph.nodes) { + const key = dedupKey(node, product.id); + const existing = grouped.get(key); + if (existing) { + if (!existing.products.some((product2) => product2.id === product.id)) { + existing.products.push({ id: product.id, name: product.name }); + } + } else { + grouped.set(key, { + node, + products: [{ id: product.id, name: product.name }], + }); + } + } + } + + return Array.from(grouped.values()).map(({ node, products }) => ({ + ...node, + products, + })); +} + +export function computeNodePeriodCost( + node: SiteNode, + waccRate: number, + storageCost: number, +): number { + return computePeriodCost( + node.monthly, + node.cost?.unit_price, + waccRate, + storageCost, + ); +} + +export function totalSiteDwellCost( + nodes: SiteNode[], + waccRate: number, + storageCost: number, +): number { + return nodes + .filter((count) => DWELL_TYPES.includes(count.type) && count.stats.n > 0) + .reduce( + (acc, count) => acc + computeNodePeriodCost(count, waccRate, storageCost), + 0, + ); +} + +export function topDwellCosts( + nodes: SiteNode[], + waccRate: number, + storageCost: number, + count: number, +): Array { + return nodes + .filter((node) => DWELL_TYPES.includes(node.type) && node.stats.n > 0) + .map((node) => ({ + ...node, + periodCost: computeNodePeriodCost(node, waccRate, storageCost), + })) + .filter((node) => node.periodCost > 0) + .sort((left, right) => right.periodCost - left.periodCost) + .slice(0, count); +} + +function planningDeviation( + node: SiteNode, + measure: BaseMeasure, +): number | null { + if (node.plan == null || node.plan <= 0) { + return null; + } + return ( + (((selectStat(node.stats, measure) ?? 0) - node.plan) / node.plan) * 100 + ); +} + +export function topPlanningMismatches( + nodes: SiteNode[], + count: number, + measure: BaseMeasure = "median", +): Array { + return nodes + .filter((node) => node.plan != null && node.plan > 0 && node.stats.n > 0) + .map((node) => ({ + ...node, + deviationPct: planningDeviation(node, measure) as number, + })) + .sort((left, right) => right.deviationPct - left.deviationPct) + .slice(0, count); +} + +export function countBadPlanningParams( + nodes: SiteNode[], + measure: BaseMeasure = "median", +): number { + return nodes.filter((node) => { + if (node.plan == null || node.plan <= 0 || node.stats.n === 0) { + return false; + } + return (selectStat(node.stats, measure) ?? 0) > node.plan * 1.2; + }).length; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/slide-over.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/slide-over.tsx new file mode 100644 index 00000000000..cdb3feff6d0 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/slide-over.tsx @@ -0,0 +1,142 @@ +import { Dialog as ArkDialog, Portal } from "@ark-ui/react"; +import { + createContext, + useCallback, + useContext, + useEffect, + useState, + type ReactNode, +} from "react"; + +import { usePortalContainerRef } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +/** + * Right-anchored slide-over (drawer) built on `@ark-ui/react/dialog`, styled with + * ds-helpers `css()` + design-system tokens. Mounted === + * open (caller conditionally renders); closes on Escape / backdrop / outside + * click. Portals into the supply-chain layout scope so tokens resolve. Caller + * owns header + body. + * + * Enter/exit animation: the panel slides via the positioner's `right` offset and + * the backdrop fades, driven by a local `visible` flag. We deliberately animate + * `right` (not `transform`) so no containing block is created — the data-table + * modal renders inline inside the content with `position: fixed` and must stay + * relative to the viewport. On close we play the exit animation, then defer the + * caller's `onClose` (which unmounts us) until the transition finishes. + */ + +const EXIT_MS = 200; + +const SlideOverCloseContext = createContext<(() => void) | null>(null); + +/** Animated close for descendants (Back / X buttons) — plays the slide-out. */ +function useSlideOverClose(): () => void { + const close = useContext(SlideOverCloseContext); + return close ?? (() => {}); +} + +/** + * Render-prop access to the slide-over's animated close. Use for in-panel Back / + * ✕ controls (e.g. a ds `Button`) so they play the exit slide instead of + * unmounting instantly — pass `close` to the control's `onClick`. Must be + * rendered inside ``. + */ +export const SlideOverClose = ({ + children, +}: { + children: (close: () => void) => ReactNode; +}) => { + const close = useSlideOverClose(); + return <>{children(close)}; +}; + +interface SlideOverProps { + onClose: () => void; + children: ReactNode; + /** Optional className for the content panel (e.g. width overrides). */ + className?: string; + /** Accessible label for the dialog. */ + label?: string; +} + +const backdropBase = css({ + position: "fixed", + inset: "0", + bg: "neutral.a80", + zIndex: "overlay", + opacity: "[0]", + transition: "[opacity 200ms ease-out]", +}); +const backdropVisible = css({ opacity: "[1]" }); + +const positionerBase = css({ + position: "fixed", + top: "0", + bottom: "0", + right: "[-960px]", + display: "flex", + zIndex: "modal", + transition: "[right 200ms ease-out]", +}); +const positionerVisible = css({ right: "0" }); + +const contentStyles = css({ + height: "full", + width: "[960px]", + maxWidth: "[90vw]", + overflowY: "auto", + bg: "bgSolid.min", + boxShadow: "2xl", +}); + +export const SlideOver = ({ + onClose, + children, + className, + label, +}: SlideOverProps) => { + const portalRef = usePortalContainerRef(); + const [visible, setVisible] = useState(false); + + useEffect(() => { + const id = requestAnimationFrame(() => setVisible(true)); + return () => cancelAnimationFrame(id); + }, []); + + const requestClose = useCallback(() => { + setVisible(false); + window.setTimeout(onClose, EXIT_MS); + }, [onClose]); + + return ( + + { + if (!details.open) { + requestClose(); + } + }} + > + + + + + {children} + + + + + + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/stat-chip.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/stat-chip.tsx new file mode 100644 index 00000000000..b278fbf15e5 --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/stat-chip.tsx @@ -0,0 +1,53 @@ +import { css, cx } from "@hashintel/ds-helpers/css"; + +// `flexWrap` lets the label drop onto its own line *under* the value when the +// chip is squeezed (value and label each stay unbroken), and sit inline beside +// it when there's room. `minW:0` lets the chip shrink to trigger that wrap. +const chip = css({ + display: "flex", + flexWrap: "wrap", + alignItems: "center", + columnGap: "1", + rowGap: "0", + minW: "0", + pr: "4", + mr: "4", + borderRightWidth: "1px", + borderColor: "bd.subtle", + _last: { borderRightWidth: "0", pr: "0", mr: "0" }, +}); +const valueBase = css({ + fontWeight: "medium", + textStyle: "sm", + fontVariantNumeric: "tabular-nums", + flexShrink: "0", +}); +const valueHighlight = css({ color: "status.error.fg.body" }); +const valuePlain = css({ color: "fg.max" }); +const labelText = css({ + textStyle: "sm", + color: "fg.subtle", + whiteSpace: "nowrap", +}); + +/** Inline labelled metric, separated from siblings by a right border. */ +export const StatChip = ({ + value, + label, + isHighlight, +}: { + value: string; + label: string; + isHighlight?: boolean; +}) => { + return ( +
    + + {value} + + {label} +
    + ); +}; diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/stats.test.ts b/apps/hash-frontend/src/pages/supply-chain/shared/stats.test.ts new file mode 100644 index 00000000000..018b7d3832a --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/stats.test.ts @@ -0,0 +1,25 @@ +import { describe, expect, it } from "vitest"; + +import { emptyStats } from "./observation-fixtures"; +import { computeStats } from "./stats"; + +describe("computeStats", () => { + it("returns zeroed stats for an empty input", () => { + expect(computeStats([])).toEqual(emptyStats); + }); + + it("computes mean/median/percentiles with linear interpolation", () => { + expect(computeStats([10, 20, 30])).toEqual({ + n: 3, + mean: 20, + median: 20, + std: 8.2, + min: 10, + max: 30, + p25: 15, + p75: 25, + p85: 27, + p95: 29, + }); + }); +}); diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/stats.ts b/apps/hash-frontend/src/pages/supply-chain/shared/stats.ts new file mode 100644 index 00000000000..112a36311cd --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/stats.ts @@ -0,0 +1,66 @@ +import type { StepStats } from "./types"; + +/** Round to one decimal place (the app's canonical display precision). */ +export function round(value: number): number { + return Math.round(value * 10) / 10; +} + +/** Percentile of a pre-sorted array via linear interpolation. */ +export function percentileOf(sorted: number[], product: number): number { + if (sorted.length === 0) { + throw new Error("Cannot compute a percentile of an empty series"); + } + const count = sorted.length; + const idx = (product / 100) * (count - 1); + const lo = Math.floor(idx); + const hi = Math.ceil(idx); + const low = sorted[lo]; + const high = sorted[hi]; + if (low === undefined || high === undefined) { + throw new Error("Percentile index was outside the provided series"); + } + if (lo === hi) { + return low; + } + return low + (high - low) * (idx - lo); +} + +/** Summary statistics (mean/median/std/percentiles) over a value set. */ +export function computeStats(values: number[]): StepStats { + if (values.length === 0) { + return { + n: 0, + mean: 0, + median: 0, + std: 0, + min: 0, + max: 0, + p25: 0, + p75: 0, + p85: 0, + p95: 0, + }; + } + const sorted = [...values].sort((left, right) => left - right); + const count = sorted.length; + const min = sorted[0]; + const max = sorted[count - 1]; + if (min === undefined || max === undefined) { + throw new Error("Cannot compute stats for an empty series"); + } + const mean = sorted.reduce((left, right) => left + right, 0) / count; + const variance = + sorted.reduce((left, right) => left + (right - mean) ** 2, 0) / count; + return { + n: count, + mean: round(mean), + median: round(percentileOf(sorted, 50)), + std: round(Math.sqrt(variance)), + min, + max, + p25: round(percentileOf(sorted, 25)), + p75: round(percentileOf(sorted, 75)), + p85: round(percentileOf(sorted, 85)), + p95: round(percentileOf(sorted, 95)), + }; +} diff --git a/apps/hash-frontend/src/pages/supply-chain/shared/status-dialog.tsx b/apps/hash-frontend/src/pages/supply-chain/shared/status-dialog.tsx new file mode 100644 index 00000000000..c51aadb285b --- /dev/null +++ b/apps/hash-frontend/src/pages/supply-chain/shared/status-dialog.tsx @@ -0,0 +1,286 @@ +import { useEffect, useRef, useState, type FormEvent } from "react"; +import { createPortal } from "react-dom"; + +import { usePortalContainerRef } from "@hashintel/ds-components"; +import { css, cx } from "@hashintel/ds-helpers/css"; + +import { + STATUS_OPTIONS, + statusCommentRequired, + type StatusOption, +} from "../app-shell/site/opportunities"; + +// `popover` sits above the slide-over (`modal`), so the dialog appears over an +// open step detail panel rather than behind it. +const backdrop = css({ + position: "fixed", + inset: "0", + zIndex: "popover", + bg: "neutral.a80", + display: "flex", + alignItems: "center", + justifyContent: "center", + p: "4", +}); +const panel = css({ + display: "flex", + flexDirection: "column", + w: "full", + maxW: "lg", + maxH: "[calc(100dvh-2rem)]", + overflowY: "auto", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "lg", + bg: "bgSolid.min", + boxShadow: "2xl", +}); +const headerRow = css({ + px: "5", + py: "4", + borderBottomWidth: "1px", + borderColor: "bd.subtle", + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", + gap: "3", +}); +const titleStyle = css({ + textStyle: "lg", + fontWeight: "semibold", + color: "fg.heading", +}); +const subtitle = css({ textStyle: "xs", color: "fg.subtle" }); +const body = css({ + px: "5", + py: "4", + display: "flex", + flexDirection: "column", + gap: "4", +}); +const radioStack = css({ display: "flex", flexDirection: "column", gap: "2" }); +const radioLabel = css({ + display: "flex", + alignItems: "center", + gap: "2", + textStyle: "sm", + color: "fg.heading", + cursor: "pointer", +}); +const textarea = css({ + minH: "28", + resize: "vertical", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + borderRadius: "md", + px: "3", + py: "2", + textStyle: "sm", + color: "fg.heading", + bg: "bgSolid.min", +}); +const errorText = css({ textStyle: "xs", color: "status.error.fg.body" }); +const footer = css({ + px: "5", + py: "4", + borderTopWidth: "1px", + borderColor: "bd.subtle", + display: "flex", + justifyContent: "flex-end", + gap: "2", +}); +// Save is first in DOM (so it's the first tab stop after the textarea) but +// rendered on the right via flex order; Cancel keeps the left slot. +const saveOrder = css({ order: "1" }); +const cancelOrder = css({ order: "0" }); +const button = css({ + display: "inline-flex", + alignItems: "center", + gap: "1", + borderRadius: "sm", + borderWidth: "1px", + borderStyle: "solid", + borderColor: "bd.subtle", + px: "2.5", + py: "1", + textStyle: "xs", + lineHeight: "none", + fontWeight: "medium", + color: "fg.muted", + cursor: "pointer", + whiteSpace: "nowrap", + _hover: { borderColor: "bd.strong", color: "fg.heading" }, +}); +const primaryButton = css({ + bg: "fg.heading", + color: "bgSolid.min", + borderColor: "fg.heading", + _hover: { bg: "fg.muted", color: "bgSolid.min" }, +}); + +const DEFAULT_STATUS: StatusOption = "investigation_started"; + +export interface StatusDialogProps { + /** Subtitle shown under the heading (e.g. the step / opportunity title). */ + title: string; + onClose: () => void; + onSave: (status: { category: StatusOption; text: string }) => void; +} + +/** + * Centered modal for leaving a status update against a step/opportunity. + * The form resets on each target change so status edits never inherit a prior + * category or comment. + */ +export const StatusDialog = ({ title, onClose, onSave }: StatusDialogProps) => { + const [category, setCategory] = useState(DEFAULT_STATUS); + const [text, setText] = useState(""); + const [error, setError] = useState(null); + const textareaRef = useRef(null); + const portalRef = usePortalContainerRef(); + + useEffect(() => { + setCategory(DEFAULT_STATUS); + setText(""); + setError(null); + textareaRef.current?.focus(); + }, []); + + const selectCategory = (next: StatusOption) => { + setCategory(next); + if (!statusCommentRequired(next)) { + setError(null); + } + textareaRef.current?.focus(); + }; + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + const trimmedText = text.trim(); + if (statusCommentRequired(category) && trimmedText.length === 0) { + setError("Add a comment for this status."); + textareaRef.current?.focus(); + return; + } + onSave({ category, text: trimmedText }); + }; + + const dialog = ( +
    { + if (event.target === event.currentTarget) { + onClose(); + } + }} + onKeyDown={(event) => { + if (event.key === "Escape") { + onClose(); + } + }} + > + {/* biome-ignore lint/a11y/useSemanticElements: a native UA positioning fights the flex-centered backdrop, so we use a div */} +
    +
    +
    +

    + Status +

    +

    {title}

    +
    + +
    +
    +
    + {STATUS_OPTIONS.map((option) => ( + + ))} +
    +