From cfd92dd87a4fc57318adbfea71b808cce8ac4ede Mon Sep 17 00:00:00 2001 From: Michael Osofsky Date: Wed, 4 Mar 2026 01:45:19 +0700 Subject: [PATCH 1/3] Add abc-supply-plan-11.3.0.json schema (#5430) * Add abc-supply-plan-11.3.0.json schema - Add abc-supply-plan-11.3.0.json schema file - Update catalog.json to include version 11.3.0 and set as default - Update schema-validation.jsonc with validation configuration - Add positive test case for version 11.3.0 - Copy negative test cases from version 11.2.0 with updated schema references Key changes in version 11.3.0: - Added "Monetary" to unit enum (alongside "Lots") - Added optional metric properties: armID, isCumulative, itemID, kitID, regionID - Removed "text" from required in analytics notes - Added "tabID" to required in analytics layout items Testing: - Validated schema-specific: node ./cli.js check --schema-name=abc-supply-plan-11.3.0.json - Validated full test suite: node ./cli.js check (all 776 tested schemas pass) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Michael Osofsky Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/api/json/catalog.json | 5 +- .../abc-supply-plan-extraneous-property.json | 15 + ...pply-plan-invalid-fractional-lot-size.json | 48 + .../abc-supply-plan-invalid-plan-date.json | 12 + ...upply-plan-invalid-strings-as-numbers.json | 48 + ...c-supply-plan-missing-schema-property.json | 11 + .../abc-supply-plan-missing-tabs.json | 11 + src/schema-validation.jsonc | 22 + src/schemas/json/abc-supply-plan-11.3.0.json | 1462 +++++++++++++++++ .../abc-supply-plan.json | 546 ++++++ 10 files changed, 2178 insertions(+), 2 deletions(-) create mode 100644 src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-extraneous-property.json create mode 100644 src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-fractional-lot-size.json create mode 100644 src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-plan-date.json create mode 100644 src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-strings-as-numbers.json create mode 100644 src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-schema-property.json create mode 100644 src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-tabs.json create mode 100644 src/schemas/json/abc-supply-plan-11.3.0.json create mode 100644 src/test/abc-supply-plan-11.3.0/abc-supply-plan.json diff --git a/src/api/json/catalog.json b/src/api/json/catalog.json index e324966644c..c728954720f 100644 --- a/src/api/json/catalog.json +++ b/src/api/json/catalog.json @@ -193,7 +193,7 @@ "name": "ABCSupplyPlan", "description": "ABCSupplyPlan representing all the state for performing inventory optimization and expiry analysis in ABC-Plan MasterPlanner", "fileMatch": ["abc-supply-plan-*.json"], - "url": "https://www.schemastore.org/abc-supply-plan-11.2.0.json", + "url": "https://www.schemastore.org/abc-supply-plan-11.3.0.json", "versions": { "1.0.0": "https://www.schemastore.org/abc-supply-plan-1.0.0.json", "2.0.0": "https://www.schemastore.org/abc-supply-plan-2.0.0.json", @@ -208,7 +208,8 @@ "10.1.0": "https://www.schemastore.org/abc-supply-plan-10.1.0.json", "11.0.0": "https://www.schemastore.org/abc-supply-plan-11.0.0.json", "11.1.0": "https://www.schemastore.org/abc-supply-plan-11.1.0.json", - "11.2.0": "https://www.schemastore.org/abc-supply-plan-11.2.0.json" + "11.2.0": "https://www.schemastore.org/abc-supply-plan-11.2.0.json", + "11.3.0": "https://www.schemastore.org/abc-supply-plan-11.3.0.json" } }, { diff --git a/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-extraneous-property.json b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-extraneous-property.json new file mode 100644 index 00000000000..4010b806c34 --- /dev/null +++ b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-extraneous-property.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "abcMaterialsMap": {}, + "analytics": { + "items": [], + "layouts": [], + "tabs": [] + }, + "planDate": "2020-03-01", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"Plan for March 2020\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": {}, + "this_is_an_invalid_property": { + "this_is_an_invalid_object_property": "this_is_an_invalid_object_value" + } +} diff --git a/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-fractional-lot-size.json b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-fractional-lot-size.json new file mode 100644 index 00000000000..bf41dead301 --- /dev/null +++ b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-fractional-lot-size.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "abcMaterialsMap": { + "1": { + "abcMaterialName": "FDP", + "actuals": {}, + "currency": "USD", + "decimalPrecision": 0, + "demand": { + "2020-07-01": 100 + }, + "doExpiryCarryover": false, + "expiryAdjustments": {}, + "firmOrders": [], + "firmRelease": {}, + "firmingPeriod": 0, + "inventory": {}, + "leadTime": 3, + "lifetime": 10, + "lotSizes": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 100.5 + } + ], + "maximumInventories": [], + "minimumInventories": [], + "ordering": 1, + "otherDemand": {}, + "otherDemandAnnotations": {}, + "plannedOrders": {}, + "plannedRelease": {}, + "productionMethod": "CumulativeLeadTime", + "timeAggregateType": "Monthly", + "x": 249, + "y": 127 + } + }, + "analytics": { + "items": [], + "layouts": [], + "tabs": [] + }, + "planDate": "2020-03-01", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"Plan for March 2020\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": {} +} diff --git a/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-plan-date.json b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-plan-date.json new file mode 100644 index 00000000000..f62840db6c0 --- /dev/null +++ b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-plan-date.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "abcMaterialsMap": {}, + "analytics": { + "items": [], + "layouts": [], + "tabs": [] + }, + "planDate": "March 1st, 2020", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"Plan for March 2020\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": {} +} diff --git a/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-strings-as-numbers.json b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-strings-as-numbers.json new file mode 100644 index 00000000000..4e906a7bd9b --- /dev/null +++ b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-invalid-strings-as-numbers.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "abcMaterialsMap": { + "1": { + "abcMaterialName": "FDP", + "actuals": {}, + "currency": "USD", + "decimalPrecision": "zero", + "demand": { + "2020-07-01": "one hundred" + }, + "doExpiryCarryover": false, + "expiryAdjustments": {}, + "firmOrders": [], + "firmRelease": {}, + "firmingPeriod": "0", + "inventory": {}, + "leadTime": "three", + "lifetime": 10, + "lotSizes": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": "2000" + } + ], + "maximumInventories": [], + "minimumInventories": [], + "ordering": 1, + "otherDemand": {}, + "otherDemandAnnotations": {}, + "plannedOrders": {}, + "plannedRelease": {}, + "productionMethod": "CumulativeLeadTime", + "timeAggregateType": "Monthly", + "x": 249, + "y": 127 + } + }, + "analytics": { + "items": [], + "layouts": [], + "tabs": [] + }, + "planDate": "2020-03-01", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"Plan for March 2020\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": {} +} diff --git a/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-schema-property.json b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-schema-property.json new file mode 100644 index 00000000000..5bed16811ea --- /dev/null +++ b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-schema-property.json @@ -0,0 +1,11 @@ +{ + "abcMaterialsMap": {}, + "analytics": { + "items": [], + "layouts": [], + "tabs": [] + }, + "planDate": "2020-03-01", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"Plan for March 2020\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": {} +} diff --git a/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-tabs.json b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-tabs.json new file mode 100644 index 00000000000..f488fb3cb1c --- /dev/null +++ b/src/negative_test/abc-supply-plan-11.3.0/abc-supply-plan-missing-tabs.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "abcMaterialsMap": {}, + "analytics": { + "items": [], + "layouts": [] + }, + "planDate": "2020-03-01", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"Plan for March 2020\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": {} +} diff --git a/src/schema-validation.jsonc b/src/schema-validation.jsonc index 226644a018a..10d4cd4ba56 100644 --- a/src/schema-validation.jsonc +++ b/src/schema-validation.jsonc @@ -700,6 +700,28 @@ "abcArePlanningFrequencyChangesOnPlanningMonths" ] }, + "abc-supply-plan-11.3.0.json": { + "unknownFormat": ["abc-draft-js_RawDraftContentState"], + "unknownKeywords": [ + "abcIsFirstDayOfMonth", + "abcIsLastDayOfMonth", + "abcIsAfter0001-01-01", + "abcIsBefore9999-12-31", + "abcDoMaterialIDsExist", + "abcIsAcyclic", + "abcAreAllocationMethodsHomogeneous", + "abcIsValidColor", + "abcNoDuplicateValuesForOrderingProperty", + "abcHasNonOverlappingTimeDependentValues", + "abcHasUninterruptedTimeDependentValues", + "abcIsExpirationDateOnOrAfterManufactureDate", + "abcIsReleaseDateOnOrAfterPlanDate", + "abcIsReleaseDateOnOrAfterManufactureDate", + "abcIsExpirationDateOnOrAfterReleaseDate", + "abcDemandDetailsMatchDemandRows", + "abcArePlanningFrequencyChangesOnPlanningMonths" + ] + }, "anywork-ac-1.0.json": { "externalSchema": ["base.json"] }, diff --git a/src/schemas/json/abc-supply-plan-11.3.0.json b/src/schemas/json/abc-supply-plan-11.3.0.json new file mode 100644 index 00000000000..e4093d8ab3c --- /dev/null +++ b/src/schemas/json/abc-supply-plan-11.3.0.json @@ -0,0 +1,1462 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "$comment": "AUTO-GENERATED by scripts/assemble-schemas.js — DO NOT EDIT BY HAND", + "title": "ABCSupplyPlan JSON Schema", + "description": "Schema defining the structure of ABCSupplyPlan used for managing plan data in ABC-Plan's MasterPlanner.", + "properties": { + "$schema": { + "description": "Link to https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "type": "string", + "enum": ["https://json.schemastore.org/abc-supply-plan-11.3.0.json"] + }, + "planDate": { + "type": "string", + "format": "date", + "title": "Plan Date", + "description": "The start date for the plan. Format: first day of a month.", + "abcIsFirstDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true + }, + "planNotes": { + "type": "string", + "format": "abc-draft-js_RawDraftContentState", + "title": "Plan Notes", + "description": "Notes or comments about the plan in a specified format. Since there is no JSON Schema for draft-js, the underlying component for mui-rte, format abc-draft-js_RawDraftContentState is enforced by calling https://draftjs.org/docs/api-reference-data-conversion/#convertfromraw. see also: https://github.com/facebookarchive/draft-js/issues/2071 and https://github.com/facebookarchive/draft-js/issues/1544" + }, + "analytics": { + "$comment": "SINGLE SOURCE OF TRUTH for analytics configuration. Used by scripts/assemble-schemas.js to replace __ABC_JSON_SCHEMA_PLACEHOLDER_ANALYTICS__ in each template. DO NOT reference this file directly — it is inlined into parent schemas at build time.", + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "title": "Analytics Item", + "description": "An analytics item that can be either a time series or an analytics note", + "oneOf": [ + { + "type": "object", + "title": "Time Series", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["TIME_SERIES"] + }, + "subtitle": { + "type": "string" + }, + "excludeMonthsFromBeginning": { + "type": "number", + "description": "Number of months to exclude from the beginning of the time series. Positive values trim, negative values add months before the plan start date." + }, + "excludeMonthsFromEnd": { + "type": "number", + "description": "Number of months to exclude from the end of the time series. Positive values trim, negative values add months after the plan end date." + }, + "timeAggregateType": { + "type": "string", + "enum": ["Annual", "Quarterly", "Monthly"], + "title": "Time Aggregate Type", + "description": "The aggregation level for time series data display" + }, + "metrics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "metricType": { + "type": "string", + "enum": [ + "demand", + "demandDetail", + "actuals", + "otherDemand", + "firmOrders", + "plannedOrders", + "firmRelease", + "plannedRelease", + "expiryAdjustments", + "inventory", + "mfc", + "targetMFC", + "capacityUtilization", + "workInProgress" + ] + }, + "abcMaterialIDs": { + "type": "array", + "items": { + "type": "string" + } + }, + "visualization": { + "type": "object", + "oneOf": [ + { + "properties": { + "type": { + "type": "string", + "enum": ["line"] + }, + "strokeWidth": { + "type": "number" + }, + "strokeDasharray": { + "type": "string" + }, + "dotSize": { + "type": "number", + "minimum": 0 + }, + "dotFill": { + "type": "string" + }, + "showDataPointValues": { + "type": "boolean", + "description": "Display data point values directly on the chart" + } + }, + "required": [ + "type", + "strokeWidth", + "strokeDasharray", + "dotSize", + "dotFill", + "showDataPointValues" + ], + "additionalProperties": false + }, + { + "properties": { + "type": { + "type": "string", + "enum": ["bar"] + }, + "barWidth": { + "type": "number" + }, + "radius": { + "type": "number" + }, + "stackId": { + "type": "string" + }, + "showAsPercent": { + "type": "boolean" + }, + "showDataPointValues": { + "type": "boolean", + "description": "Display data point values directly on the chart" + } + }, + "required": [ + "type", + "barWidth", + "radius", + "stackId", + "showAsPercent", + "showDataPointValues" + ], + "additionalProperties": false + }, + { + "properties": { + "type": { + "type": "string", + "enum": ["area"] + }, + "fillOpacity": { + "type": "number" + }, + "strokeWidth": { + "type": "number" + }, + "stackId": { + "type": "string" + }, + "showAsPercent": { + "type": "boolean" + }, + "showDataPointValues": { + "type": "boolean", + "description": "Display data point values directly on the chart" + } + }, + "required": [ + "type", + "fillOpacity", + "strokeWidth", + "stackId", + "showAsPercent", + "showDataPointValues" + ], + "additionalProperties": false + } + ] + }, + "yAxisIndex": { + "type": "number" + }, + "color": { + "type": "string" + }, + "zIndex": { + "type": "number" + }, + "label": { + "type": "string" + }, + "showQuantitiesAs": { + "type": ["string", "null"], + "oneOf": [ + { + "type": "string", + "enum": ["Units", "Lots", "Monetary"] + }, + { + "type": "null" + } + ], + "title": "Show Quantities As", + "description": "How to display the quantities for this metric" + }, + "comparisonPlanID": { + "type": ["string", "null"], + "title": "Comparison Plan ID", + "description": "The ID of the comparison plan to use for this metric or null if no comparison plan is used" + }, + "regionID": { + "type": "string", + "title": "Region ID", + "description": "Optional region filter for Clinical Demand Forecast metrics" + }, + "armID": { + "type": "string", + "title": "Arm ID", + "description": "Optional treatment arm filter for Clinical Demand Forecast metrics" + }, + "kitID": { + "type": "string", + "title": "Kit ID", + "description": "Optional kit filter for Clinical Demand Forecast metrics" + }, + "itemID": { + "type": "string", + "title": "Item ID", + "description": "Optional item filter for Clinical Demand Forecast metrics" + }, + "isCumulative": { + "type": "boolean", + "title": "Is Cumulative", + "description": "Whether to display cumulative values" + } + }, + "required": [ + "metricType", + "abcMaterialIDs", + "visualization", + "yAxisIndex", + "color", + "zIndex", + "label", + "showQuantitiesAs", + "comparisonPlanID" + ], + "allOf": [ + { + "if": { + "properties": { + "metricType": { + "const": "mfc" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "type": "null" + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "targetMFC" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "type": "null" + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "otherDemand" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "type": "null" + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "capacityUtilization" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "type": "null" + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "demand" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "enum": ["Units", "Monetary"] + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "actuals" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "enum": ["Units", "Monetary"] + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "firmRelease" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "enum": ["Units", "Lots", "Monetary"] + } + } + } + }, + { + "if": { + "properties": { + "metricType": { + "const": "plannedRelease" + } + } + }, + "then": { + "properties": { + "showQuantitiesAs": { + "enum": ["Units", "Lots", "Monetary"] + } + } + } + } + ], + "additionalProperties": false + } + } + }, + "required": [ + "id", + "name", + "type", + "subtitle", + "excludeMonthsFromBeginning", + "excludeMonthsFromEnd", + "timeAggregateType", + "metrics" + ], + "additionalProperties": false + }, + { + "type": "object", + "title": "Analytics Note Item", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["ANALYTICS_NOTE"] + }, + "subtitle": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "imageUrl": { + "type": "string" + }, + "text": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "fontFamily": { + "type": "string" + }, + "fontSize": { + "type": "number" + }, + "color": { + "type": "string" + }, + "horizontalAlignment": { + "type": "string", + "enum": ["left", "center", "right"] + }, + "verticalAlignment": { + "type": "string", + "enum": ["top", "center", "bottom"] + } + }, + "required": [ + "content", + "fontFamily", + "fontSize", + "color", + "horizontalAlignment", + "verticalAlignment" + ], + "additionalProperties": false + } + }, + "required": ["id", "name", "type", "subtitle"], + "additionalProperties": false + }, + { + "type": "object", + "title": "Demand/Consumption Allocation Item", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["DEMAND_OR_CONSUMPTION_ALLOCATION"] + }, + "subtitle": { + "type": "string" + }, + "materialId": { + "type": "string", + "description": "Single material ID for demand details analysis" + }, + "visualizationType": { + "type": "string", + "enum": ["PIE_CHART", "TIME_SERIES"], + "description": "Visualization type for the demand details" + }, + "chartType": { + "type": "string", + "enum": ["line", "bar", "area"], + "description": "Chart type for time series visualization (defaults to bar)" + }, + "excludeMonthsFromBeginning": { + "type": "number", + "description": "Months to exclude from plan start (default: 0)" + }, + "excludeMonthsFromEnd": { + "type": "number", + "description": "Months to exclude from plan end (default: 0)" + }, + "timeAggregateType": { + "type": "string", + "enum": ["Annual", "Quarterly", "Monthly"], + "description": "Time aggregation type for TIME_SERIES mode" + }, + "displayConfig": { + "type": "object", + "properties": { + "showTopN": { + "type": "number", + "description": "Show top N categories" + }, + "showOther": { + "type": "boolean", + "description": "Group remaining into Other" + }, + "showPercentages": { + "type": "boolean", + "description": "Show percentages in labels" + }, + "showLegend": { + "type": "boolean", + "description": "Show legend" + }, + "minSlicePercentage": { + "type": "number", + "description": "Min percentage to show separately" + } + }, + "required": [ + "showTopN", + "showOther", + "showPercentages", + "showLegend", + "minSlicePercentage" + ], + "additionalProperties": false + }, + "planId": { + "type": "string", + "description": "Optional plan ID for comparison" + } + }, + "required": [ + "id", + "name", + "type", + "subtitle", + "materialId", + "visualizationType" + ], + "additionalProperties": false + } + ] + } + }, + "layouts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "contentId": { + "type": "string" + }, + "x": { + "type": "number", + "minimum": 0, + "maximum": 11, + "description": "Grid column position (0-11 for 12-column grid)" + }, + "y": { + "type": "number", + "minimum": 0, + "description": "Grid row position" + }, + "tabID": { + "type": "string", + "description": "ID of the tab this layout item belongs to" + }, + "w": { + "type": "number", + "minimum": 1, + "maximum": 12, + "description": "Width in grid units (1-12)" + }, + "h": { + "type": "number", + "minimum": 1, + "description": "Height in grid units" + }, + "minH": { + "type": "number", + "minimum": 1, + "description": "Minimum height in grid units" + }, + "maxH": { + "type": "number", + "minimum": 1, + "description": "Maximum height in grid units" + }, + "minW": { + "type": "number", + "minimum": 1, + "description": "Minimum width in grid units" + }, + "maxW": { + "type": "number", + "minimum": 1, + "description": "Maximum width in grid units" + }, + "isDraggable": { + "type": "boolean", + "description": "Whether the item can be dragged" + }, + "isResizable": { + "type": "boolean", + "description": "Whether the item can be resized" + } + }, + "required": ["contentId", "x", "y", "tabID", "w", "h"], + "additionalProperties": false + } + }, + "tabs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "ordering": { + "type": "number" + } + }, + "required": ["id", "name", "ordering"], + "additionalProperties": false + } + } + }, + "required": ["items", "layouts", "tabs"], + "additionalProperties": false + }, + "abcMaterialsMap": { + "type": "object", + "patternProperties": { + "^\\d+$": { + "$ref": "#/definitions/ABCMaterialState" + } + }, + "additionalProperties": false, + "title": "ABC Materials Map", + "description": "A mapping of material IDs to their respective states within the ABC system.", + "abcNoDuplicateValuesForOrderingProperty": true + }, + "recipeMap": { + "type": "object", + "patternProperties": { + "^\\d+-\\d+$": { + "$ref": "#/definitions/RecipeState" + } + }, + "additionalProperties": false, + "title": "Recipe Map", + "description": "A mapping of recipes, representing the acyclic relationships among materials. abcAreAllocationMethodsHomogeneous requires no mixing of Allocation Methods. A downstream material cannot have mixed upstream recipes. An upstream material cannot have mixed downstream recipes.", + "abcDoMaterialIDsExist": true, + "abcIsAcyclic": true, + "abcAreAllocationMethodsHomogeneous": true + } + }, + "required": [ + "$schema", + "planDate", + "planNotes", + "analytics", + "abcMaterialsMap", + "recipeMap" + ], + "additionalProperties": false, + "type": "object", + "definitions": { + "ABCMaterialState": { + "type": "object", + "title": "ABC Material State", + "description": "Represents the state of a material in the system including its attributes and planning parameters.", + "abcDemandDetailsMatchDemandRows": true, + "properties": { + "x": { + "type": "number", + "title": "X Coordinate", + "description": "The X coordinate position of the material in a graphical representation." + }, + "y": { + "type": "number", + "title": "Y Coordinate", + "description": "The Y coordinate position of the material in a graphical representation." + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Numeric value representing the order or sequence of the material." + }, + "abcMaterialName": { + "type": "string", + "minLength": 1, + "title": "Material Name", + "description": "The name of the material." + }, + "uom": { + "type": "string", + "minLength": 1, + "title": "Unit of Measure", + "description": "The unit of measure used for the material." + }, + "materialShape": { + "type": "string", + "enum": [ + "circle", + "square", + "diamond", + "rectangle", + "parallelogram", + "trapezoid", + "triangle", + "pentagon", + "hexagon" + ], + "title": "Material Shape", + "description": "The shape of the material represented graphically." + }, + "materialColor": { + "$ref": "#/definitions/Color" + }, + "doExpiryCarryover": { + "type": "boolean", + "title": "Expiry Carryover", + "description": "Indicates whether to carry over the expiry information for the material." + }, + "isCapacityConstraintNode": { + "type": "boolean", + "title": "Capacity Constraint Node", + "description": "Determines if the material is a node where capacity constraints are applied." + }, + "inventoryMethod": { + "type": "string", + "enum": ["TargetMFC", "MinimumInventory"], + "title": "Inventory Method", + "description": "The method used for managing inventory levels, either target months forward coverage or minimum inventory." + }, + "decimalPrecision": { + "type": "integer", + "minimum": 0, + "maximum": 5, + "title": "Decimal Precision", + "description": "The precision of decimal places allowed for numerical entries related to the material." + }, + "currency": { + "type": "string", + "minLength": 1, + "title": "Currency", + "description": "The currency used for monetary calculations of the material." + }, + "manufacturingCost": { + "type": "number", + "minimum": 0, + "title": "Manufacturing Cost", + "description": "The direct manufacturing cost per unit of the material." + }, + "standardCost": { + "type": "number", + "minimum": 0, + "title": "Standard Cost", + "description": "The standard cost per unit including overhead of the material." + }, + "salesPrice": { + "type": "number", + "minimum": 0, + "title": "Sales Price", + "description": "The sales price per unit of the material." + }, + "lotSize": { + "$comment": "Require integer until we fix https://gitlab.com/abc-plan/abc-plan-server/-/issues/9", + "type": "integer", + "minimum": 1, + "title": "Lot Size", + "description": "Batch size for orders. Must be greater than 0 to plan, etc." + }, + "leadTime": { + "type": "integer", + "minimum": 0, + "title": "Lead Time", + "description": "Delay between Manufacture Date and Release Date. Format: non-negative integer." + }, + "firmingPeriod": { + "type": "integer", + "minimum": 0, + "title": "Firming Period", + "description": "Time during which no Planned Orders are allowed. Format: non-negative integer." + }, + "targetMFCs": { + "$ref": "#/definitions/NonNegativeIntegerTimeDependentValues", + "title": "Target MFC", + "description": "Target Months Forward Coverage refers to a dynamic safety stock level—a buffer quantity of inventory designed to mitigate the risk of stock-outs caused by variability in Demand. In essence, it represents the number of months of Demand that could be satisfied assuming no additional material is manufactured. Each value is defined for a specific period of time." + }, + "minimumInventories": { + "$ref": "#/definitions/NonNegativeIntegerTimeDependentValues", + "title": "Minimum Inventory", + "description": "List of Minimum Inventory values, each defined for a specific period of time. Minimum Inventory denotes the lowest stock level to prevent outages, triggering restock." + }, + "planningFrequencies": { + "$ref": "#/definitions/PositiveIntegerTimeDependentValues", + "title": "Planning Frequencies", + "description": "List of Planning Frequency values, each defined for a specific period of time.", + "abcArePlanningFrequencyChangesOnPlanningMonths": true + }, + "shelfLives": { + "$ref": "#/definitions/NonNegativeIntegerTimeDependentValues", + "title": "Shelf Lives", + "description": "List of Shelf Life values, each defined for a specific period of time." + }, + "stopshipBuffers": { + "$ref": "#/definitions/NonNegativeIntegerTimeDependentValues", + "title": "Stopship Buffers", + "description": "Buffers to account for Stopship scenarios, listed for different periods." + }, + "initialInventories": { + "type": "array", + "items": { + "$ref": "#/definitions/InitialInventory" + }, + "title": "Initial Inventories", + "description": "List of Initial Inventory records, each associated with specific lot and dates." + }, + "firmOrders": { + "type": "array", + "items": { + "$ref": "#/definitions/FirmOrder" + }, + "title": "Firm Orders", + "description": "List of Firm Orders with their respective quantities and dates." + }, + "demand": { + "$ref": "#/definitions/PositiveDateMapMap", + "title": "Demand", + "description": "Map of demand rows, where each key is a unique ID and value is a DateMap containing demand values for specific dates." + }, + "demandDetails": { + "$ref": "#/definitions/ABCDemandDetailsMap", + "title": "Demand/Consumption Allocation", + "description": "Mapping of demand row IDs to their metadata including labels and ordering." + }, + "otherDemand": { + "$ref": "#/definitions/PositiveDateMap", + "title": "Other Demand", + "description": "Map of other types of demand not included in the primary demand values." + }, + "otherDemandAnnotation": { + "$ref": "#/definitions/AnnotationMap", + "title": "Other Demand Annotation", + "description": "Annotations related to other demand entries, providing additional context." + }, + "actuals": { + "$ref": "#/definitions/PositiveDateMap", + "title": "Actuals", + "description": "Map of actual quantities, corresponding to real data collected." + }, + "plannedOrders": { + "$ref": "#/definitions/PositiveDateMap", + "title": "Planned Orders", + "description": "Map of planned order quantities, anticipated ahead of time." + }, + "expiryAdjustments": { + "$ref": "#/definitions/NegativeDateMap", + "title": "Expiry Adjustments", + "description": "Adjustments made to account for expired materials, reducing quantities." + }, + "timeAggregateType": { + "type": "string", + "enum": ["Annual", "Quarterly", "Monthly"], + "title": "Time Aggregate Type", + "description": "The aggregation level for planning and reporting, e.g., annual, quarterly, or monthly." + }, + "showQuantitiesAs": { + "type": "string", + "enum": ["Units", "Lots", "Monetary"], + "title": "Show Quantities As", + "description": "Defines how quantities are represented, e.g., in units, lots, or monetary value." + }, + "expiryAnalysisType": { + "type": "string", + "enum": ["Expiration", "Stopship"], + "title": "Expiry Analysis Type", + "description": "Determines the type of analysis to be performed on expiry data, focusing on expiration or stopship scenarios." + }, + "timeDependentPlanningParameters": { + "type": "boolean", + "title": "Time Dependent Planning Parameters", + "description": "Indicates whether planning parameters are dependent on time, necessitating different values at different periods." + }, + "inventorySystemMaterialNumber": { + "title": "Material Number in the inventory management system", + "description": "For pulling inventory from the inventory management system into Initial Inventory and Firm Orders & Releases", + "type": ["string", "null"] + }, + "inventorySystemLocationName": { + "title": "Location in the inventory management system", + "description": "For pulling inventory from the inventory management system into Initial Inventory and Firm Orders & Releases and filtering it by location", + "type": ["string", "null"] + } + }, + "required": [ + "x", + "y", + "ordering", + "abcMaterialName", + "uom", + "materialShape", + "materialColor", + "doExpiryCarryover", + "isCapacityConstraintNode", + "inventoryMethod", + "decimalPrecision", + "currency", + "manufacturingCost", + "standardCost", + "salesPrice", + "lotSize", + "leadTime", + "firmingPeriod", + "targetMFCs", + "minimumInventories", + "planningFrequencies", + "shelfLives", + "stopshipBuffers", + "initialInventories", + "firmOrders", + "demand", + "demandDetails", + "actuals", + "expiryAdjustments", + "otherDemand", + "otherDemandAnnotation", + "plannedOrders", + "timeAggregateType", + "showQuantitiesAs", + "expiryAnalysisType", + "timeDependentPlanningParameters", + "inventorySystemMaterialNumber", + "inventorySystemLocationName" + ], + "additionalProperties": false, + "allOf": [ + { + "if": { + "properties": { + "timeDependentPlanningParameters": { + "const": false + } + } + }, + "then": { + "properties": { + "targetMFCs": { + "type": "array", + "maxItems": 1, + "minItems": 1 + }, + "minimumInventories": { + "type": "array", + "maxItems": 1, + "minItems": 1 + }, + "planningFrequencies": { + "type": "array", + "maxItems": 1, + "minItems": 1 + }, + "shelfLives": { + "type": "array", + "maxItems": 1, + "minItems": 1 + }, + "stopshipBuffers": { + "type": "array", + "maxItems": 1, + "minItems": 1 + } + } + } + }, + { + "if": { + "properties": { + "timeDependentPlanningParameters": { + "const": true + } + } + }, + "then": { + "properties": { + "targetMFCs": { + "type": "array", + "minItems": 1 + }, + "minimumInventories": { + "type": "array", + "minItems": 1 + }, + "planningFrequencies": { + "type": "array", + "minItems": 1 + }, + "shelfLives": { + "type": "array", + "minItems": 1 + }, + "stopshipBuffers": { + "type": "array", + "minItems": 1 + } + } + } + } + ] + }, + "RecipeState": { + "type": "object", + "title": "Recipe State", + "description": "Defines a recipe within the system, including its components and yields.", + "properties": { + "recipe": { + "type": "number", + "exclusiveMinimum": 0, + "title": "Recipe ID", + "description": "Unique identifier of the recipe." + }, + "allocationMethod": { + "type": "string", + "enum": ["PercentAllocation", "PriorityAllocation"], + "title": "Consumption Allocation", + "description": "Method for allocating downstream consumption to upstream materials." + }, + "percentAllocations": { + "$ref": "#/definitions/PercentTimeDependentValues", + "title": "Percent Allocations", + "description": "Percentage allocations of materials to the recipe over different periods." + }, + "priorityAllocations": { + "$ref": "#/definitions/NonNegativeNumberTimeDependentValues", + "title": "Priority Allocations", + "description": "Priority allocations of materials to the recipe over different periods." + }, + "percentYield": { + "type": "number", + "minimum": 0, + "title": "Percent Yield", + "description": "The yield percentage of the recipe, indicating efficiency." + } + }, + "required": [ + "recipe", + "allocationMethod", + "percentAllocations", + "priorityAllocations", + "percentYield" + ], + "additionalProperties": false + }, + "PositiveDateMap": { + "type": "object", + "title": "Positive Date Map", + "description": "Mapping of dates to positive numerical values, typically representing demand or supply quantities.", + "patternProperties": { + "^\\d{4}-(0[1-9]|1[0-2])-01$": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "PositiveDateMapMap": { + "type": "object", + "title": "Positive Date Map Map", + "description": "Mapping of unique IDs to date maps, supporting multiple demand rows per material.", + "patternProperties": { + "^.*$": { + "$ref": "#/definitions/PositiveDateMap" + } + }, + "additionalProperties": false + }, + "NegativeDateMap": { + "type": "object", + "title": "Negative Date Map", + "description": "Mapping of dates to negative numerical values, typically representing adjustments or reductions.", + "patternProperties": { + "^\\d{4}-(0[1-9]|1[0-2])-01$": { + "type": "number", + "maximum": 0 + } + }, + "additionalProperties": false + }, + "AnnotationMap": { + "type": "object", + "title": "Annotation Map", + "description": "Mapping of dates to annotations or notes about specific entries.", + "patternProperties": { + "^\\d{4}-(0[1-9]|1[0-2])-01$": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Color": { + "type": "string", + "title": "Color", + "description": "Colors may be specified in any string-based format supported by the Color constructor documented at https://www.npmjs.com/package/color", + "abcIsValidColor": "true" + }, + "ABCDemandDetailsMap": { + "type": "object", + "title": "ABC Demand/Consumption Allocation Map", + "description": "Mapping of demand row IDs to their metadata including label and ordering.", + "patternProperties": { + "^.*$": { + "type": "object", + "properties": { + "label": { + "type": "string", + "title": "Label", + "description": "User-visible label for the demand row." + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Display order of the demand row within a material." + } + }, + "required": ["label", "ordering"], + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "TemplateTimeDependentValue": { + "$comment": "additionalProperties is true because this object acts as a template and is merged with other type definitions to specify valid date ranges for time-dependent values.", + "type": "object", + "title": "Template Time Dependent Value", + "description": "Base template for defining time-dependent values, specifying the valid date ranges for such values.", + "properties": { + "startDate": { + "title": "Start Date", + "description": "The start date for the time-dependent value. Must be the first day of a month and within a valid date range.", + "oneOf": [ + { + "type": "string", + "format": "date", + "abcIsFirstDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true + }, + { + "type": "null" + } + ] + }, + "endDate": { + "title": "End Date", + "description": "The end date for the time-dependent value. Must be the last day of a month and within a valid date range.", + "oneOf": [ + { + "type": "string", + "format": "date", + "abcIsLastDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true + }, + { + "type": "null" + } + ] + } + }, + "required": ["startDate", "endDate"], + "additionalProperties": true + }, + "PercentValueConstraints": { + "$comment": "additionalProperties is true because it is a template and gets merged with other types", + "type": "object", + "title": "Percent Value Constraints", + "description": "Constraints for percentage values, defining the valid range as 0% to 100%.", + "properties": { + "timeDependentValue": { + "description": "During a particular period of time for this recipe, how much of the downstream consumption is allocated to the upstream material. Format: 0-1 which correspond to 0%-100%.", + "type": "number", + "minimum": 0, + "maximum": 1 + } + }, + "required": ["timeDependentValue"], + "additionalProperties": true + }, + "PercentTimeDependentValue": { + "allOf": [ + { + "$ref": "#/definitions/TemplateTimeDependentValue" + }, + { + "$ref": "#/definitions/PercentValueConstraints" + } + ], + "title": "Percent Time Dependent Value", + "description": "Defines a time-specific percentage value within a valid date range, adhering to percentage constraints." + }, + "PercentTimeDependentValues": { + "type": "array", + "items": { + "$ref": "#/definitions/PercentTimeDependentValue" + }, + "title": "Percent Time Dependent Values", + "description": "Array of time-dependent percentage values, each specifying the allocation for a given period.", + "abcHasNonOverlappingTimeDependentValues": "true", + "abcHasUninterruptedTimeDependentValues": "true" + }, + "NonNegativeIntegerConstraints": { + "$comment": "additionalProperties is true because this object acts as a template and is merged with other type definitions to enforce non-negative integer constraints in various scenarios.", + "type": "object", + "title": "Non-Negative Integer Constraints", + "description": "Defines constraints for integer values to ensure they are non-negative, used in various time-dependent value configurations.", + "properties": { + "timeDependentValue": { + "type": "integer", + "minimum": 0, + "title": "Time Dependent Value", + "description": "An integer value that cannot be negative, typically representing quantities or counts in a time-dependent context." + } + }, + "required": ["timeDependentValue"], + "additionalProperties": true + }, + "NonNegativeIntegerTimeDependentValue": { + "allOf": [ + { + "$ref": "#/definitions/TemplateTimeDependentValue" + }, + { + "$ref": "#/definitions/NonNegativeIntegerConstraints" + } + ], + "title": "Non-Negative Integer Time Dependent Value", + "description": "Defines a time-specific integer value within a valid date range, ensuring it is non-negative." + }, + "NonNegativeIntegerTimeDependentValues": { + "type": "array", + "items": { + "$ref": "#/definitions/NonNegativeIntegerTimeDependentValue" + }, + "title": "Non-Negative Integer Time Dependent Values", + "description": "Array of time-dependent integer values, ensuring each is non-negative.", + "abcHasNonOverlappingTimeDependentValues": "true", + "abcHasUninterruptedTimeDependentValues": "true" + }, + "NonNegativeNumberConstraints": { + "$comment": "additionalProperties is true to allow merging this object with other type definitions to enforce non-negative number constraints in various scenarios.", + "type": "object", + "title": "Non-Negative Number Constraints", + "description": "Defines constraints for numbers to ensure they are non-negative, used in various contexts.", + "properties": { + "timeDependentValue": { + "type": "number", + "minimum": 0, + "title": "Non-Negative Number", + "description": "A non-negative number, used in various contexts to represent quantities or counts." + } + }, + "required": ["timeDependentValue"], + "additionalProperties": true + }, + "NonNegativeNumberTimeDependentValue": { + "allOf": [ + { + "$ref": "#/definitions/TemplateTimeDependentValue" + }, + { + "$ref": "#/definitions/NonNegativeNumberConstraints" + } + ], + "title": "Non-Negative Number Time Dependent Value", + "description": "Defines a time-specific number within a valid range, ensuring it is non-negative." + }, + "NonNegativeNumberTimeDependentValues": { + "type": "array", + "items": { + "$ref": "#/definitions/NonNegativeNumberTimeDependentValue" + }, + "title": "Non-Negative Number Time Dependent Values", + "description": "Array of time-dependent non-negative numbers.", + "abcHasNonOverlappingTimeDependentValues": "true", + "abcHasUninterruptedTimeDependentValues": "true" + }, + "PositiveIntegerConstraints": { + "$comment": "additionalProperties is set to true because this object acts as a template and is merged with other type definitions to enforce positive integer constraints in various scenarios.", + "type": "object", + "title": "Positive Integer Constraints", + "description": "Defines constraints for integer values to ensure they are positive, used in various configurations where a strictly positive value is required.", + "properties": { + "timeDependentValue": { + "type": "integer", + "minimum": 1, + "title": "Time Dependent Value", + "description": "An integer value that must be positive, typically representing quantities or counts in contexts where zero is not a valid value." + } + }, + "required": ["timeDependentValue"], + "additionalProperties": true + }, + "PositiveIntegerTimeDependentValue": { + "allOf": [ + { + "$ref": "#/definitions/TemplateTimeDependentValue" + }, + { + "$ref": "#/definitions/PositiveIntegerConstraints" + } + ], + "title": "Positive Integer Time Dependent Value", + "description": "Defines a time-specific integer value that must always be positive, ensuring it meets the requirements of scenarios where zero or negative numbers are not permitted." + }, + "PositiveIntegerTimeDependentValues": { + "type": "array", + "items": { + "$ref": "#/definitions/PositiveIntegerTimeDependentValue" + }, + "title": "Positive Integer Time Dependent Values", + "description": "Array of time-dependent integer values, ensuring each is positive. This setup is intended for scenarios where values must always be greater than zero.", + "abcHasNonOverlappingTimeDependentValues": "true", + "abcHasUninterruptedTimeDependentValues": "true" + }, + "InitialInventory": { + "type": "object", + "title": "Initial Inventory", + "description": "Defines the initial inventory of a material, including lot number and associated dates.", + "properties": { + "lotNumber": { + "type": "string", + "minLength": 1, + "title": "Lot Number", + "description": "The identifier for the lot number of the inventory item. It must be at least 1 character in length." + }, + "initialInventoryQuantity": { + "type": "number", + "minimum": 0, + "title": "Initial Inventory Quantity", + "description": "The quantity of the inventory item when first recorded. This must be a non-negative number." + }, + "manufactureDate": { + "type": "string", + "format": "date", + "title": "Manufacture Date", + "description": "The date the item was manufactured. This date must be the first day of a month and fall within a valid date range.", + "abcIsFirstDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true + }, + "expirationDate": { + "type": "string", + "format": "date", + "title": "Expiration Date", + "description": "The date the item will expire. This date must be the last day of a month and fall within a valid date range.", + "abcIsLastDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true, + "abcIsExpirationDateOnOrAfterManufactureDate": true + } + }, + "required": [ + "lotNumber", + "initialInventoryQuantity", + "manufactureDate", + "expirationDate" + ], + "additionalProperties": false + }, + "FirmOrder": { + "type": "object", + "title": "Firm Order", + "description": "Defines a firm order within the system, including order details and relevant dates.", + "properties": { + "firmOrderName": { + "type": "string", + "title": "Firm Order Name", + "description": "The name or identifier of the firm order." + }, + "firmOrderQuantity": { + "type": "number", + "minimum": 0, + "title": "Firm Order Quantity", + "description": "The quantity specified in the firm order. Must be a non-negative value." + }, + "manufactureDate": { + "type": "string", + "format": "date", + "title": "Manufacture Date", + "description": "The date the goods are scheduled to be manufactured. Must be the first day of the month and within valid date range.", + "abcIsFirstDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true + }, + "releaseDate": { + "type": "string", + "format": "date", + "title": "Release Date", + "description": "The date the goods are scheduled to be released. Must be the first day of the month and within valid date range.", + "abcIsFirstDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true, + "abcIsReleaseDateOnOrAfterPlanDate": true, + "abcIsReleaseDateOnOrAfterManufactureDate": true + }, + "expirationDate": { + "type": "string", + "format": "date", + "title": "Expiration Date", + "description": "The expiration date of the product. Must be the last day of the month and within valid date range.", + "abcIsLastDayOfMonth": true, + "abcIsAfter0001-01-01": true, + "abcIsBefore9999-12-31": true, + "abcIsExpirationDateOnOrAfterReleaseDate": true + } + }, + "required": [ + "firmOrderName", + "firmOrderQuantity", + "manufactureDate", + "releaseDate", + "expirationDate" + ], + "additionalProperties": false + } + } +} diff --git a/src/test/abc-supply-plan-11.3.0/abc-supply-plan.json b/src/test/abc-supply-plan-11.3.0/abc-supply-plan.json new file mode 100644 index 00000000000..09a9e1c5277 --- /dev/null +++ b/src/test/abc-supply-plan-11.3.0/abc-supply-plan.json @@ -0,0 +1,546 @@ +{ + "$schema": "https://json.schemastore.org/abc-supply-plan-11.3.0.json", + "abcMaterialsMap": { + "1": { + "abcMaterialName": "FDP", + "actuals": {}, + "currency": "USD", + "decimalPrecision": 0, + "demand": { + "1": { + "2020-03-01": 0, + "2020-04-01": 2117, + "2020-05-01": 2214, + "2020-06-01": 2285, + "2020-07-01": 2516, + "2020-08-01": 2675, + "2020-09-01": 2833, + "2020-10-01": 3006, + "2020-11-01": 3196, + "2020-12-01": 3414, + "2021-01-01": 3630, + "2021-02-01": 3859, + "2021-03-01": 4105, + "2021-04-01": 4369, + "2021-05-01": 4651, + "2021-06-01": 4948, + "2021-07-01": 5263, + "2021-08-01": 5600, + "2021-09-01": 5959, + "2021-10-01": 6341, + "2021-11-01": 6748, + "2021-12-01": 7180, + "2022-01-01": 7639, + "2022-02-01": 8128, + "2022-03-01": 8648, + "2022-04-01": 9202, + "2022-05-01": 9791, + "2022-06-01": 10417 + } + }, + "demandDetails": { + "1": { + "label": "Default Demand", + "ordering": 1 + } + }, + "doExpiryCarryover": false, + "expiryAdjustments": { + "2020-03-01": 0, + "2020-04-01": 0, + "2020-05-01": 0, + "2020-06-01": 0, + "2020-07-01": 0, + "2020-08-01": 0, + "2020-09-01": 0, + "2020-10-01": 0, + "2020-11-01": 0, + "2020-12-01": 0, + "2021-01-01": 0, + "2021-02-01": 0, + "2021-03-01": 0, + "2021-04-01": 0, + "2021-05-01": 0, + "2021-06-01": 0, + "2021-07-01": 0, + "2021-08-01": 0, + "2021-09-01": 0, + "2021-10-01": 0, + "2021-11-01": 0, + "2021-12-01": 0, + "2022-01-01": 0, + "2022-02-01": 0, + "2022-03-01": 0, + "2022-04-01": 0, + "2022-05-01": 0, + "2022-06-01": 0 + }, + "expiryAnalysisType": "Expiration", + "firmOrders": [ + { + "expirationDate": "2021-03-31", + "firmOrderName": "Sep Firm Order", + "firmOrderQuantity": 2000, + "manufactureDate": "2020-09-01", + "releaseDate": "2020-10-01" + }, + { + "expirationDate": "2021-05-31", + "firmOrderName": "Nov Firm Order", + "firmOrderQuantity": 4000, + "manufactureDate": "2020-11-01", + "releaseDate": "2020-12-01" + }, + { + "expirationDate": "2021-08-31", + "firmOrderName": "Feb Firm Order", + "firmOrderQuantity": 4000, + "manufactureDate": "2021-02-01", + "releaseDate": "2021-03-01" + }, + { + "expirationDate": "2021-07-31", + "firmOrderName": "Jan Firm Order", + "firmOrderQuantity": 4000, + "manufactureDate": "2021-01-01", + "releaseDate": "2021-02-01" + }, + { + "expirationDate": "2021-06-30", + "firmOrderName": "Dec Firm Order", + "firmOrderQuantity": 4000, + "manufactureDate": "2020-12-01", + "releaseDate": "2021-01-01" + } + ], + "firmingPeriod": 6, + "initialInventories": [ + { + "expirationDate": "2020-07-31", + "initialInventoryQuantity": 8000, + "lotNumber": "old lot", + "manufactureDate": "2020-01-01" + } + ], + "inventoryMethod": "TargetMFC", + "inventorySystemLocationName": null, + "inventorySystemMaterialNumber": null, + "isCapacityConstraintNode": false, + "leadTime": 1, + "lotSize": 2000, + "manufacturingCost": 0, + "materialColor": "#3D85C6", + "materialShape": "circle", + "minimumInventories": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "ordering": 0, + "otherDemand": { + "2020-03-01": 0, + "2020-04-01": 0, + "2020-05-01": 0, + "2020-06-01": 0, + "2020-07-01": 0, + "2020-08-01": 0, + "2020-09-01": 0, + "2020-10-01": 0, + "2020-11-01": 0, + "2020-12-01": 0, + "2021-01-01": 0, + "2021-02-01": 0, + "2021-03-01": 0, + "2021-04-01": 0, + "2021-05-01": 0, + "2021-06-01": 0, + "2021-07-01": 0, + "2021-08-01": 0, + "2021-09-01": 0, + "2021-10-01": 0, + "2021-11-01": 0, + "2021-12-01": 0, + "2022-01-01": 0, + "2022-02-01": 0, + "2022-03-01": 0, + "2022-04-01": 0, + "2022-05-01": 0, + "2022-06-01": 0 + }, + "otherDemandAnnotation": {}, + "plannedOrders": { + "2020-09-01": 16000, + "2020-10-01": 4000, + "2020-11-01": 0, + "2020-12-01": 2000, + "2021-01-01": 0, + "2021-02-01": 2000, + "2021-03-01": 6000, + "2021-04-01": 4000, + "2021-05-01": 8000, + "2021-06-01": 6000, + "2021-07-01": 8000, + "2021-08-01": 6000, + "2021-09-01": 10000, + "2021-10-01": 8000, + "2021-11-01": 8000, + "2021-12-01": 10000, + "2022-01-01": 12000, + "2022-02-01": 0, + "2022-03-01": 0, + "2022-04-01": 0, + "2022-05-01": 0 + }, + "planningFrequencies": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "salesPrice": 0, + "shelfLives": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 6 + } + ], + "showQuantitiesAs": "Units", + "standardCost": 0, + "stopshipBuffers": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "targetMFCs": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 4 + } + ], + "timeAggregateType": "Monthly", + "timeDependentPlanningParameters": false, + "uom": "bottle", + "x": 258, + "y": 75 + }, + "2": { + "abcMaterialName": "DP", + "actuals": {}, + "currency": "USD", + "decimalPrecision": 0, + "demand": {}, + "demandDetails": {}, + "doExpiryCarryover": false, + "expiryAdjustments": {}, + "expiryAnalysisType": "Expiration", + "firmOrders": [], + "firmingPeriod": 0, + "initialInventories": [], + "inventoryMethod": "TargetMFC", + "inventorySystemLocationName": null, + "inventorySystemMaterialNumber": null, + "isCapacityConstraintNode": false, + "leadTime": 0, + "lotSize": 333221, + "manufacturingCost": 0, + "materialColor": "#3D85C6", + "materialShape": "circle", + "minimumInventories": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "ordering": 1, + "otherDemand": {}, + "otherDemandAnnotation": {}, + "plannedOrders": { + "2020-03-01": 0, + "2020-04-01": 0, + "2020-05-01": 0, + "2020-06-01": 0, + "2020-07-01": 0, + "2020-08-01": 0, + "2020-09-01": 666442, + "2020-10-01": 0, + "2020-11-01": 333221, + "2020-12-01": 0, + "2021-01-01": 333221, + "2021-02-01": 0, + "2021-03-01": 333221, + "2021-04-01": 0, + "2021-05-01": 333221, + "2021-06-01": 0, + "2021-07-01": 333221, + "2021-08-01": 333221, + "2021-09-01": 333221, + "2021-10-01": 0, + "2021-11-01": 333221, + "2021-12-01": 333221, + "2022-01-01": 333221, + "2022-02-01": 0, + "2022-03-01": 0, + "2022-04-01": 0, + "2022-05-01": 0, + "2022-06-01": 0 + }, + "planningFrequencies": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "salesPrice": 0, + "shelfLives": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "showQuantitiesAs": "Units", + "standardCost": 0, + "stopshipBuffers": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "targetMFCs": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "timeAggregateType": "Monthly", + "timeDependentPlanningParameters": false, + "uom": "tab", + "x": 258, + "y": 275 + }, + "3": { + "abcMaterialName": "API", + "actuals": {}, + "currency": "USD", + "decimalPrecision": 0, + "demand": {}, + "demandDetails": {}, + "doExpiryCarryover": false, + "expiryAdjustments": {}, + "expiryAnalysisType": "Expiration", + "firmOrders": [], + "firmingPeriod": 0, + "initialInventories": [], + "inventoryMethod": "TargetMFC", + "inventorySystemLocationName": null, + "inventorySystemMaterialNumber": null, + "isCapacityConstraintNode": false, + "leadTime": 0, + "lotSize": 333221, + "manufacturingCost": 0, + "materialColor": "#3D85C6", + "materialShape": "circle", + "minimumInventories": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "ordering": 2, + "otherDemand": {}, + "otherDemandAnnotation": {}, + "plannedOrders": { + "2020-03-01": 0, + "2020-04-01": 0, + "2020-05-01": 0, + "2020-06-01": 0, + "2020-07-01": 0, + "2020-08-01": 0, + "2020-09-01": 333221, + "2020-10-01": 0, + "2020-11-01": 333221, + "2020-12-01": 0, + "2021-01-01": 0, + "2021-02-01": 0, + "2021-03-01": 333221, + "2021-04-01": 0, + "2021-05-01": 0, + "2021-06-01": 0, + "2021-07-01": 333221, + "2021-08-01": 0, + "2021-09-01": 333221, + "2021-10-01": 0, + "2021-11-01": 0, + "2021-12-01": 333221, + "2022-01-01": 0, + "2022-02-01": 0, + "2022-03-01": 0, + "2022-04-01": 0, + "2022-05-01": 0, + "2022-06-01": 0 + }, + "planningFrequencies": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "salesPrice": 0, + "shelfLives": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "showQuantitiesAs": "Units", + "standardCost": 0, + "stopshipBuffers": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "targetMFCs": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 0 + } + ], + "timeAggregateType": "Monthly", + "timeDependentPlanningParameters": false, + "uom": "mg", + "x": 258, + "y": 475 + } + }, + "analytics": { + "items": [ + { + "excludeMonthsFromBeginning": 0, + "excludeMonthsFromEnd": 0, + "id": "1738852054957", + "metrics": [ + { + "abcMaterialIDs": ["1"], + "color": "#1976d2", + "comparisonPlanID": null, + "label": "Inventory", + "metricType": "inventory", + "showQuantitiesAs": "Units", + "visualization": { + "barWidth": 20, + "radius": 0, + "showAsPercent": false, + "showDataPointValues": false, + "stackId": "", + "type": "bar" + }, + "yAxisIndex": 0, + "zIndex": 0 + }, + { + "abcMaterialIDs": ["1"], + "color": "#E69138", + "comparisonPlanID": null, + "label": "MFC", + "metricType": "mfc", + "showQuantitiesAs": null, + "visualization": { + "dotFill": "#ffffff", + "dotSize": 4, + "showDataPointValues": false, + "strokeDasharray": "", + "strokeWidth": 2, + "type": "line" + }, + "yAxisIndex": 1, + "zIndex": 0 + } + ], + "name": "Inventory vs. MFC", + "subtitle": "FDP", + "timeAggregateType": "Monthly", + "type": "TIME_SERIES" + } + ], + "layouts": [ + { + "contentId": "1738852054957", + "h": 6, + "isDraggable": true, + "isResizable": true, + "minH": 2, + "minW": 1, + "tabID": "1", + "w": 7, + "x": 0, + "y": 0 + } + ], + "tabs": [ + { + "id": "1", + "name": "Overview", + "ordering": 1 + } + ] + }, + "planDate": "2020-03-01", + "planNotes": "{\"blocks\":[{\"key\":\"8o58p\",\"text\":\"\u00c6\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}", + "recipeMap": { + "1-2": { + "allocationMethod": "PercentAllocation", + "percentAllocations": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "percentYield": 1, + "priorityAllocations": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "recipe": 30 + }, + "2-3": { + "allocationMethod": "PercentAllocation", + "percentAllocations": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "percentYield": 1, + "priorityAllocations": [ + { + "endDate": null, + "startDate": null, + "timeDependentValue": 1 + } + ], + "recipe": 0.5 + } + } +} From 4fa7fc3c3cf892101e61df9e2e4ae59fab4a4fa2 Mon Sep 17 00:00:00 2001 From: Michael Osofsky Date: Wed, 4 Mar 2026 01:45:58 +0700 Subject: [PATCH 2/3] Introduce abc-clinical-demand-forecast-1.0.0.json schema (#5432) * Introduce abc-clinical-demand-forecast-1.0.0.json schema - Add abc-clinical-demand-forecast-1.0.0.json schema file (first-time publish) - Add new ABCClinicalDemandForecast entry in catalog.json - Add schema-validation.jsonc entry for custom keyword abcHasValidKitItemReferences - Add positive test case for version 1.0.0 - Add negative test case (missing $schema property) abc-clinical-demand-forecast-1.0.0.json is a JSON Schema defining the structure of ABCClinicalDemandForecast used for clinical trial demand forecasting in ABC-Plan. This includes study overview, enrollment configuration, dosing regimens, arms, regions, kits, items, sites, and analytics. Testing: - Validated schema-specific: node ./cli.js check --schema-name=abc-clinical-demand-forecast-1.0.0.json - Validated full test suite: node ./cli.js check (all 776 tested schemas pass) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Michael Osofsky Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/api/json/catalog.json | 9 + ...mand-forecast-missing-schema-property.json | 10 + src/schema-validation.jsonc | 3 + .../abc-clinical-demand-forecast-1.0.0.json | 1822 +++++++++++++++++ .../abc-clinical-demand-forecast.json | 237 +++ 5 files changed, 2081 insertions(+) create mode 100644 src/negative_test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast-missing-schema-property.json create mode 100644 src/schemas/json/abc-clinical-demand-forecast-1.0.0.json create mode 100644 src/test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast.json diff --git a/src/api/json/catalog.json b/src/api/json/catalog.json index c728954720f..b0beff4e6cc 100644 --- a/src/api/json/catalog.json +++ b/src/api/json/catalog.json @@ -189,6 +189,15 @@ "5.1.0": "https://www.schemastore.org/abc-inventory-module-data-5.1.0.json" } }, + { + "name": "ABCClinicalDemandForecast", + "description": "ABCClinicalDemandForecast defining the structure of clinical trial demand forecasting data in ABC-Plan", + "fileMatch": ["abc-clinical-demand-forecast-*.json"], + "url": "https://www.schemastore.org/abc-clinical-demand-forecast-1.0.0.json", + "versions": { + "1.0.0": "https://www.schemastore.org/abc-clinical-demand-forecast-1.0.0.json" + } + }, { "name": "ABCSupplyPlan", "description": "ABCSupplyPlan representing all the state for performing inventory optimization and expiry analysis in ABC-Plan MasterPlanner", diff --git a/src/negative_test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast-missing-schema-property.json b/src/negative_test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast-missing-schema-property.json new file mode 100644 index 00000000000..98b90a2643c --- /dev/null +++ b/src/negative_test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast-missing-schema-property.json @@ -0,0 +1,10 @@ +{ + "analytics": { + "items": [], + "layouts": [], + "tabs": [] + }, + "clinicalDemandCalculatedForecast": null, + "clinicalDemandForecastConfiguration": {}, + "planNotes": "" +} diff --git a/src/schema-validation.jsonc b/src/schema-validation.jsonc index 10d4cd4ba56..99db70bb68c 100644 --- a/src/schema-validation.jsonc +++ b/src/schema-validation.jsonc @@ -431,6 +431,9 @@ "https://raw.githubusercontent.com/ShaitanLyss/these/main/hecate/hecate-json-schema.json" ], "options": { + "abc-clinical-demand-forecast-1.0.0.json": { + "unknownKeywords": ["abcHasValidKitItemReferences"] + }, "abc-supply-plan-1.0.0.json": { "unknownFormat": ["abc-draft-js_RawDraftContentState"], "unknownKeywords": [ diff --git a/src/schemas/json/abc-clinical-demand-forecast-1.0.0.json b/src/schemas/json/abc-clinical-demand-forecast-1.0.0.json new file mode 100644 index 00000000000..feac6be6671 --- /dev/null +++ b/src/schemas/json/abc-clinical-demand-forecast-1.0.0.json @@ -0,0 +1,1822 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://json.schemastore.org/abc-clinical-demand-forecast-1.0.0.json", + "$comment": "AUTO-GENERATED by scripts/assemble-schemas.js — DO NOT EDIT BY HAND", + "title": "ABCClinicalDemandForecast JSON Schema", + "description": "Schema defining the structure of ABCClinicalDemandForecast used for clinical trial demand forecasting in ABC-Plan.", + "type": "object", + "properties": { + "$schema": { + "description": "Link to https://json.schemastore.org/abc-clinical-demand-forecast-1.0.0.json", + "type": "string", + "enum": [ + "https://json.schemastore.org/abc-clinical-demand-forecast-1.0.0.json" + ] + }, + "planNotes": { + "type": "string", + "title": "Plan Notes", + "description": "Optional notes about the clinical demand forecast plan." + }, + "analytics": { + "$comment": "SINGLE SOURCE OF TRUTH for analytics configuration. Used by scripts/assemble-schemas.js to replace __ABC_JSON_SCHEMA_PLACEHOLDER_ANALYTICS__ in each template. DO NOT reference this file directly — it is inlined into parent schemas at build time.", + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "title": "Analytics Item", + "description": "An analytics item that can be either a time series or an analytics note", + "oneOf": [ + { + "type": "object", + "title": "Time Series", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["TIME_SERIES"] + }, + "subtitle": { + "type": "string" + }, + "excludeMonthsFromBeginning": { + "type": "number", + "description": "Number of months to exclude from the beginning of the time series. Positive values trim, negative values add months before the plan start date." + }, + "excludeMonthsFromEnd": { + "type": "number", + "description": "Number of months to exclude from the end of the time series. Positive values trim, negative values add months after the plan end date." + }, + "timeAggregateType": { + "type": "string", + "enum": ["Annual", "Quarterly", "Monthly"], + "title": "Time Aggregate Type", + "description": "The aggregation level for time series data display" + }, + "metrics": { + "type": "array", + "items": { + "type": "object", + "properties": { + "metricType": { + "type": "string", + "enum": [ + "enrolled", + "active", + "completed", + "kitDemand", + "sites", + "screened", + "screenedOut", + "droppedOut", + "siteSeedingKitDemand", + "kitItemDemand" + ] + }, + "abcMaterialIDs": { + "type": "array", + "items": { + "type": "string" + } + }, + "visualization": { + "type": "object", + "oneOf": [ + { + "properties": { + "type": { + "type": "string", + "enum": ["line"] + }, + "strokeWidth": { + "type": "number" + }, + "strokeDasharray": { + "type": "string" + }, + "dotSize": { + "type": "number", + "minimum": 0 + }, + "dotFill": { + "type": "string" + }, + "showDataPointValues": { + "type": "boolean", + "description": "Display data point values directly on the chart" + } + }, + "required": [ + "type", + "strokeWidth", + "strokeDasharray", + "dotSize", + "dotFill", + "showDataPointValues" + ], + "additionalProperties": false + }, + { + "properties": { + "type": { + "type": "string", + "enum": ["bar"] + }, + "barWidth": { + "type": "number" + }, + "radius": { + "type": "number" + }, + "stackId": { + "type": "string" + }, + "showAsPercent": { + "type": "boolean" + }, + "showDataPointValues": { + "type": "boolean", + "description": "Display data point values directly on the chart" + } + }, + "required": [ + "type", + "barWidth", + "radius", + "stackId", + "showAsPercent", + "showDataPointValues" + ], + "additionalProperties": false + }, + { + "properties": { + "type": { + "type": "string", + "enum": ["area"] + }, + "fillOpacity": { + "type": "number" + }, + "strokeWidth": { + "type": "number" + }, + "stackId": { + "type": "string" + }, + "showAsPercent": { + "type": "boolean" + }, + "showDataPointValues": { + "type": "boolean", + "description": "Display data point values directly on the chart" + } + }, + "required": [ + "type", + "fillOpacity", + "strokeWidth", + "stackId", + "showAsPercent", + "showDataPointValues" + ], + "additionalProperties": false + } + ] + }, + "yAxisIndex": { + "type": "number" + }, + "color": { + "type": "string" + }, + "zIndex": { + "type": "number" + }, + "label": { + "type": "string" + }, + "showQuantitiesAs": { + "type": ["string", "null"], + "oneOf": [ + { + "type": "string", + "enum": ["Units", "Lots", "Monetary"] + }, + { + "type": "null" + } + ], + "title": "Show Quantities As", + "description": "How to display the quantities for this metric" + }, + "comparisonPlanID": { + "type": ["string", "null"], + "title": "Comparison Plan ID", + "description": "The ID of the comparison plan to use for this metric or null if no comparison plan is used" + }, + "regionID": { + "type": "string", + "title": "Region ID", + "description": "Optional region filter for Clinical Demand Forecast metrics" + }, + "armID": { + "type": "string", + "title": "Arm ID", + "description": "Optional treatment arm filter for Clinical Demand Forecast metrics" + }, + "kitID": { + "type": "string", + "title": "Kit ID", + "description": "Optional kit filter for Clinical Demand Forecast metrics" + }, + "itemID": { + "type": "string", + "title": "Item ID", + "description": "Optional item filter for Clinical Demand Forecast metrics" + }, + "isCumulative": { + "type": "boolean", + "title": "Is Cumulative", + "description": "Whether to display cumulative values" + } + }, + "required": [ + "metricType", + "abcMaterialIDs", + "visualization", + "yAxisIndex", + "color", + "zIndex", + "label", + "showQuantitiesAs", + "comparisonPlanID" + ], + "additionalProperties": false + } + } + }, + "required": [ + "id", + "name", + "type", + "subtitle", + "excludeMonthsFromBeginning", + "excludeMonthsFromEnd", + "timeAggregateType", + "metrics" + ], + "additionalProperties": false + }, + { + "type": "object", + "title": "Analytics Note Item", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string", + "enum": ["ANALYTICS_NOTE"] + }, + "subtitle": { + "type": "string" + }, + "backgroundColor": { + "type": "string" + }, + "imageUrl": { + "type": "string" + }, + "text": { + "type": "object", + "properties": { + "content": { + "type": "string" + }, + "fontFamily": { + "type": "string" + }, + "fontSize": { + "type": "number" + }, + "color": { + "type": "string" + }, + "horizontalAlignment": { + "type": "string", + "enum": ["left", "center", "right"] + }, + "verticalAlignment": { + "type": "string", + "enum": ["top", "center", "bottom"] + } + }, + "required": [ + "content", + "fontFamily", + "fontSize", + "color", + "horizontalAlignment", + "verticalAlignment" + ], + "additionalProperties": false + } + }, + "required": ["id", "name", "type", "subtitle"], + "additionalProperties": false + } + ] + } + }, + "layouts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "contentId": { + "type": "string" + }, + "x": { + "type": "number", + "minimum": 0, + "maximum": 11, + "description": "Grid column position (0-11 for 12-column grid)" + }, + "y": { + "type": "number", + "minimum": 0, + "description": "Grid row position" + }, + "tabID": { + "type": "string", + "description": "ID of the tab this layout item belongs to" + }, + "w": { + "type": "number", + "minimum": 1, + "maximum": 12, + "description": "Width in grid units (1-12)" + }, + "h": { + "type": "number", + "minimum": 1, + "description": "Height in grid units" + }, + "minH": { + "type": "number", + "minimum": 1, + "description": "Minimum height in grid units" + }, + "maxH": { + "type": "number", + "minimum": 1, + "description": "Maximum height in grid units" + }, + "minW": { + "type": "number", + "minimum": 1, + "description": "Minimum width in grid units" + }, + "maxW": { + "type": "number", + "minimum": 1, + "description": "Maximum width in grid units" + }, + "isDraggable": { + "type": "boolean", + "description": "Whether the item can be dragged" + }, + "isResizable": { + "type": "boolean", + "description": "Whether the item can be resized" + } + }, + "required": ["contentId", "x", "y", "tabID", "w", "h"], + "additionalProperties": false + } + }, + "tabs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "ordering": { + "type": "number" + } + }, + "required": ["id", "name", "ordering"], + "additionalProperties": false + } + } + }, + "required": ["items", "layouts", "tabs"], + "additionalProperties": false + }, + "clinicalDemandForecastConfiguration": { + "$ref": "#/definitions/ClinicalDemandForecastConfiguration", + "title": "Clinical Demand Forecast Configuration", + "description": "All algorithm inputs that affect forecast calculation. Any change to this object invalidates clinicalDemandCalculatedForecast." + }, + "clinicalDemandCalculatedForecast": { + "$ref": "#/definitions/ClinicalDemandCalculatedForecast", + "title": "Clinical Demand Calculated Forecast", + "description": "Calculated demand forecast with atomic monthly data per-region, per-arm." + } + }, + "required": [ + "planNotes", + "analytics", + "clinicalDemandForecastConfiguration", + "clinicalDemandCalculatedForecast" + ], + "abcHasValidKitItemReferences": true, + "additionalProperties": false, + "definitions": { + "ClinicalDemandForecastConfiguration": { + "type": "object", + "title": "Clinical Demand Forecast Configuration", + "description": "All algorithm inputs that affect forecast calculation. Any change to this object should invalidate the calculated forecast.", + "properties": { + "studyOverview": { + "$ref": "#/definitions/StudyOverview", + "title": "Study Overview", + "description": "Basic information about the clinical trial study." + }, + "enrollment": { + "$ref": "#/definitions/Enrollment", + "title": "Enrollment", + "description": "Patient enrollment targets and rates." + }, + "kitConfiguration": { + "type": "object", + "title": "Kit Configuration", + "description": "Configuration of kits with containers and items, keyed by kit ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/Kit" + } + }, + "additionalProperties": false + }, + "dosingRegimens": { + "type": "object", + "title": "Dosing Regimens", + "description": "Available dosing regimens for the study, keyed by ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/DosingRegimen" + } + }, + "additionalProperties": false + }, + "treatmentArms": { + "type": "object", + "title": "Treatment Arms", + "description": "Treatment arms in the clinical trial, keyed by ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/TreatmentArm" + } + }, + "additionalProperties": false + }, + "subjectFlow": { + "$ref": "#/definitions/SubjectFlow", + "title": "Subject Flow", + "description": "Site supply and region configuration." + }, + "actuals": { + "$ref": "#/definitions/ClinicalDemandActuals", + "title": "Clinical Demand Actuals", + "description": "Actual enrollment data entered by users to reconcile with forecast." + }, + "trialDesign": { + "type": "string", + "title": "Trial Design", + "description": "Trial design type: parallel (single regimen per arm) or crossOver (sequence of treatments with washout periods).", + "enum": ["parallel", "crossOver"], + "default": "parallel" + } + }, + "required": [ + "studyOverview", + "enrollment", + "kitConfiguration", + "dosingRegimens", + "treatmentArms", + "subjectFlow", + "actuals", + "trialDesign" + ], + "additionalProperties": false + }, + "StudyOverview": { + "type": "object", + "title": "Study Overview", + "description": "Basic study information from wizard step 1.", + "properties": { + "studyName": { + "type": "string", + "title": "Study Name", + "description": "Name of the clinical trial study." + }, + "studyPhase": { + "type": "string", + "title": "Study Phase", + "description": "Phase of the clinical trial.", + "enum": ["phase_i", "phase_ii", "phase_iii", "phase_iv"] + }, + "protocolSummary": { + "type": "string", + "title": "Protocol Summary", + "description": "Summary of the trial protocol. Optional field with recommended default: empty string." + }, + "therapeuticArea": { + "type": "string", + "title": "Therapeutic Area", + "description": "Disease category being treated (e.g., Oncology, CNS, Rare Disease). Will be normalized by LLM for benchmarking. Required field with recommended default: empty string." + } + }, + "required": [ + "studyName", + "studyPhase", + "protocolSummary", + "therapeuticArea" + ], + "additionalProperties": false + }, + "Enrollment": { + "type": "object", + "title": "Enrollment", + "description": "Enrollment configuration from wizard step 2.", + "properties": { + "targetCompleted": { + "type": "integer", + "title": "Target Completed", + "description": "Target number of subjects to complete the trial.", + "minimum": 0 + }, + "screenFailureRate": { + "type": "number", + "title": "Screen Failure Rate", + "description": "Percentage of subjects who fail screening (0-100).", + "minimum": 0, + "maximum": 100 + }, + "attritionRate": { + "type": "number", + "title": "Attrition Rate", + "description": "Percentage of enrolled subjects who drop out of the study entirely and stop receiving all doses (0-100). NOTE: This is different from adverse events in dose escalation regimens. Attrition causes subjects to exit the study early, while adverse events only prevent dose escalation but subjects continue receiving doses at their maximum tolerated level.", + "minimum": 0, + "maximum": 100 + } + }, + "required": ["targetCompleted", "screenFailureRate", "attritionRate"], + "additionalProperties": false + }, + "Kit": { + "type": "object", + "title": "Kit", + "description": "A kit containing items and containers. The kit ID is the key in the kitConfiguration map.", + "properties": { + "name": { + "type": "string", + "title": "Kit Name", + "description": "Display name of the kit." + }, + "items": { + "type": "object", + "title": "Items", + "description": "Items and containers within this kit, keyed by node ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/KitNode" + } + }, + "additionalProperties": false + } + }, + "required": ["name", "items"], + "additionalProperties": false + }, + "KitNode": { + "oneOf": [ + { + "$ref": "#/definitions/KitContainer" + }, + { + "$ref": "#/definitions/KitItem" + } + ] + }, + "KitContainer": { + "type": "object", + "title": "Kit Container", + "description": "A structural container (bottle, blister pack) that holds other nodes. The container ID is the key in the parent items/children map.", + "properties": { + "nodeType": { + "type": "string", + "const": "container", + "title": "Node Type", + "description": "Discriminator identifying this as a container node." + }, + "name": { + "type": "string", + "title": "Name", + "description": "Name of the container." + }, + "deliveryForm": { + "type": "string", + "title": "Delivery Form", + "description": "Type of container.", + "enum": ["bottle", "carton", "dose_pack", "blister_pack"] + }, + "children": { + "type": "object", + "title": "Children", + "description": "Items contained within this container, keyed by node ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/KitNode" + } + }, + "additionalProperties": false + }, + "ordering": { + "type": "integer", + "title": "Ordering", + "description": "Display order of this node within its parent. Lower numbers appear first." + } + }, + "required": ["nodeType", "name", "deliveryForm", "children", "ordering"], + "additionalProperties": false + }, + "KitItem": { + "type": "object", + "title": "Kit Item", + "description": "An actual pharmaceutical item (tablet, capsule, vial) with dosage. The item ID is the key in the parent items/children map.", + "properties": { + "nodeType": { + "type": "string", + "const": "item", + "title": "Node Type", + "description": "Discriminator identifying this as an item node." + }, + "name": { + "type": "string", + "title": "Name", + "description": "Name of the item." + }, + "deliveryForm": { + "type": "string", + "title": "Delivery Form", + "description": "Type of pharmaceutical item.", + "enum": ["tablet", "capsule", "vial", "syringe", "sachet"] + }, + "quantity": { + "type": "integer", + "title": "Quantity", + "description": "Number of units contained in this item within one kit. For example, if this is a bottle containing tablets, quantity=10 means the bottle contains 10 tablets. This is NOT the same as dosingRegimen.kitItemQuantities, which specifies consumption per dose. This quantity field defines the container/packaging size.", + "minimum": 0 + }, + "dosage": { + "type": "number", + "title": "Dosage", + "description": "Dosage amount.", + "minimum": 0 + }, + "units": { + "type": "string", + "title": "Units", + "description": "Units of dosage (e.g., mg, ml)." + }, + "ordering": { + "type": "integer", + "title": "Ordering", + "description": "Display order of this node within its parent. Lower numbers appear first." + } + }, + "required": [ + "nodeType", + "name", + "deliveryForm", + "quantity", + "dosage", + "units", + "ordering" + ], + "additionalProperties": false + }, + "DosingRegimen": { + "type": "object", + "title": "Dosing Regimen", + "description": "Dosing regimen configuration with nested dosingRegimenDefinition discriminated union.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of the dosing regimen." + }, + "description": { + "type": "string", + "title": "Description", + "description": "Description of the dosing regimen." + }, + "dosingRegimenDefinition": { + "oneOf": [ + { + "$ref": "#/definitions/ActiveRegimenDefinition" + }, + { + "$ref": "#/definitions/PlaceboRegimenDefinition" + } + ], + "title": "Dosing Regimen Definition", + "description": "Discriminated union: either an active regimen definition (isPlacebo: false) or a placebo definition (isPlacebo: true)." + } + }, + "required": ["name", "description", "dosingRegimenDefinition"], + "additionalProperties": false + }, + "ActiveRegimenDefinition": { + "type": "object", + "title": "Active Regimen Definition", + "description": "Definition for an active (non-placebo) dosing regimen.", + "properties": { + "isPlacebo": { + "type": "boolean", + "const": false, + "title": "Is Placebo", + "description": "Discriminator: false for active regimens." + }, + "treatmentDuration": { + "type": "number", + "title": "Treatment Duration", + "description": "Total duration of treatment for all subjects.", + "minimum": 0 + }, + "treatmentDurationUnit": { + "type": "string", + "title": "Treatment Duration Unit", + "description": "Unit of treatment duration.", + "enum": ["days", "weeks", "months", "years"] + }, + "dosingFrequency": { + "type": "string", + "title": "Dosing Frequency", + "description": "Frequency of dose administration.", + "enum": [ + "once_daily_qd", + "twice_daily_bid", + "three_times_daily_tid", + "four_times_daily_qid", + "once_weekly_qw", + "every_2_weeks_q2w", + "every_3_weeks_q3w", + "every_4_weeks_q4w", + "monthly", + "every_6_weeks_q6w", + "every_8_weeks_q8w", + "every_12_weeks_q12w", + "every_other_day" + ] + }, + "fixedConfig": { + "anyOf": [ + { + "$ref": "#/definitions/FixedDoseConfig" + }, + { + "type": "null" + } + ], + "title": "Fixed Dose Configuration", + "description": "Configuration for fixed dose regimens. Null if using another regimen type." + }, + "doseEscalationConfig": { + "anyOf": [ + { + "$ref": "#/definitions/DoseEscalationConfig" + }, + { + "type": "null" + } + ], + "title": "Dose Escalation Configuration", + "description": "Configuration for dose escalation regimens. Null if using another regimen type." + }, + "weightBasedConfig": { + "anyOf": [ + { + "$ref": "#/definitions/WeightBasedConfig" + }, + { + "type": "null" + } + ], + "title": "Weight-Based Configuration", + "description": "Configuration for weight-based dosing regimens. Null if using another regimen type." + }, + "ageBasedConfig": { + "anyOf": [ + { + "$ref": "#/definitions/AgeBasedConfig" + }, + { + "type": "null" + } + ], + "title": "Age-Based Configuration", + "description": "Configuration for age-based dosing regimens. Null if using another regimen type." + } + }, + "required": [ + "isPlacebo", + "treatmentDuration", + "treatmentDurationUnit", + "dosingFrequency", + "fixedConfig", + "doseEscalationConfig", + "weightBasedConfig", + "ageBasedConfig" + ], + "additionalProperties": false + }, + "PlaceboRegimenDefinition": { + "type": "object", + "title": "Placebo Regimen Definition", + "description": "Definition for a placebo regimen that references an active regimen.", + "properties": { + "isPlacebo": { + "type": "boolean", + "const": true, + "title": "Is Placebo", + "description": "Discriminator: true for placebo regimens." + }, + "placeboOf": { + "type": "string", + "title": "Placebo Of", + "description": "ID of the active dosing regimen this placebo references. Placebo inherits all dosing configuration from the active regimen." + } + }, + "required": ["isPlacebo", "placeboOf"], + "additionalProperties": false + }, + "FixedDoseConfig": { + "type": "object", + "title": "Fixed Dose Configuration", + "description": "Configuration for fixed dose regimens.", + "properties": { + "kitItemQuantities": { + "type": "object", + "title": "Kit Item Quantities", + "description": "Mapping of kit item IDs to quantities consumed per dose.", + "patternProperties": { + ".*": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + } + }, + "required": ["kitItemQuantities"], + "additionalProperties": false + }, + "DoseEscalationConfig": { + "type": "object", + "title": "Dose Escalation Configuration", + "description": "Configuration for dose escalation levels.", + "properties": { + "levels": { + "type": "object", + "title": "Escalation Levels", + "description": "Map of level IDs to dose escalation levels. Use ordering property to maintain display order.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/DoseEscalationLevel" + } + }, + "additionalProperties": false + } + }, + "required": ["levels"], + "additionalProperties": false + }, + "DoseEscalationLevel": { + "title": "Dose Escalation Level", + "description": "Individual dose escalation level configuration. This is a discriminated union with three variants: First level (isFirstLevel=true), Intermediate level (isFinalLevel=false, has adverseEventRate), and Final level (isFinalLevel=true, no duration).", + "oneOf": [ + { + "$ref": "#/definitions/DoseEscalationLevelFirst" + }, + { + "$ref": "#/definitions/DoseEscalationLevelIntermediate" + }, + { + "$ref": "#/definitions/DoseEscalationLevelFinal" + } + ] + }, + "DoseEscalationLevelBase": { + "$comment": "additionalProperties is true because this object acts as a base schema and is composed with variant-specific definitions via allOf.", + "type": "object", + "title": "Dose Escalation Level Base", + "description": "Base properties shared by all dose escalation level variants.", + "properties": { + "kitItemQuantities": { + "type": "object", + "title": "Kit Item Quantities", + "description": "Mapping of kit item IDs to quantities consumed per dose at this escalation level.", + "patternProperties": { + ".*": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Display order of this level within the escalation sequence. Lower numbers appear first." + } + }, + "required": ["kitItemQuantities", "ordering"], + "additionalProperties": true + }, + "DoseEscalationLevelFirst": { + "title": "First Dose Escalation Level", + "description": "First escalation level. Has isFirstLevel=true, isFinalLevel=false, duration and durationUnit. Does NOT have adverseEventRate because adverse events occur when trialing a level, and there is no previous level to trial from.", + "allOf": [ + { + "$ref": "#/definitions/DoseEscalationLevelBase" + }, + { + "type": "object", + "properties": { + "kitItemQuantities": {}, + "isFirstLevel": { + "type": "boolean", + "const": true, + "title": "Is First Level", + "description": "Must be true for first level." + }, + "isFinalLevel": { + "type": "boolean", + "const": false, + "title": "Is Final Level", + "description": "Must be false for first level (first level cannot also be final)." + }, + "duration": { + "type": "number", + "title": "Duration", + "description": "Duration of this escalation level.", + "exclusiveMinimum": 0 + }, + "durationUnit": { + "type": "string", + "title": "Duration Unit", + "description": "Unit of duration for this level.", + "enum": ["days", "weeks", "months", "years"] + }, + "ordering": {} + }, + "required": [ + "isFirstLevel", + "isFinalLevel", + "duration", + "durationUnit" + ], + "additionalProperties": false + } + ] + }, + "DoseEscalationLevelIntermediate": { + "title": "Intermediate Dose Escalation Level", + "description": "Intermediate escalation level (not first, not final). Has isFinalLevel=false, duration, durationUnit, and adverseEventRate. Does NOT have isFirstLevel property.", + "allOf": [ + { + "$ref": "#/definitions/DoseEscalationLevelBase" + }, + { + "type": "object", + "properties": { + "kitItemQuantities": {}, + "isFinalLevel": { + "type": "boolean", + "const": false, + "title": "Is Final Level", + "description": "Must be false for intermediate level." + }, + "duration": { + "type": "number", + "title": "Duration", + "description": "Duration of this escalation level.", + "exclusiveMinimum": 0 + }, + "durationUnit": { + "type": "string", + "title": "Duration Unit", + "description": "Unit of duration for this level.", + "enum": ["days", "weeks", "months", "years"] + }, + "adverseEventRate": { + "type": "number", + "title": "Adverse Event Rate", + "description": "Percentage of subjects who experience adverse events when TRIALING THIS level from the previous level.", + "minimum": 0, + "maximum": 100 + }, + "ordering": {} + }, + "required": [ + "isFinalLevel", + "duration", + "durationUnit", + "adverseEventRate" + ], + "additionalProperties": false + } + ] + }, + "DoseEscalationLevelFinal": { + "title": "Final Dose Escalation Level", + "description": "Final escalation level. Has isFinalLevel=true and adverseEventRate. Does NOT have duration or durationUnit (subjects continue at final level until treatment ends).", + "allOf": [ + { + "$ref": "#/definitions/DoseEscalationLevelBase" + }, + { + "type": "object", + "properties": { + "kitItemQuantities": {}, + "isFinalLevel": { + "type": "boolean", + "const": true, + "title": "Is Final Level", + "description": "Must be true for final level." + }, + "adverseEventRate": { + "type": "number", + "title": "Adverse Event Rate", + "description": "Percentage of subjects who experience adverse events when TRIALING THIS level from the previous level.", + "minimum": 0, + "maximum": 100 + }, + "ordering": {} + }, + "required": ["isFinalLevel", "adverseEventRate"], + "additionalProperties": false + } + ] + }, + "WeightBasedConfig": { + "type": "object", + "title": "Weight-Based Configuration", + "description": "Configuration for weight-based dosing.", + "properties": { + "weightUnit": { + "type": "string", + "title": "Weight Unit", + "description": "Unit of weight measurement.", + "enum": ["lbs", "kg"] + }, + "ranges": { + "type": "object", + "title": "Weight Ranges", + "description": "Map of range IDs to weight ranges for kit assignment. Use ordering property to maintain display order.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/WeightRange" + } + }, + "additionalProperties": false + } + }, + "required": ["weightUnit", "ranges"], + "additionalProperties": false + }, + "WeightRange": { + "type": "object", + "title": "Weight Range", + "description": "Weight range configuration for dosing.", + "properties": { + "kitItemQuantities": { + "type": "object", + "title": "Kit Item Quantities", + "description": "Mapping of kit item IDs to quantities consumed per dose for subjects in THIS weight range. Each value represents the number of units (e.g., tablets) of that item required for a single dose. Different weight ranges can specify different quantities for the same item.", + "patternProperties": { + ".*": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "fromWeight": { + "type": ["number", "null"], + "title": "From Weight", + "description": "Minimum weight for this range (null for no lower bound).", + "minimum": 0 + }, + "toWeight": { + "type": ["number", "null"], + "title": "To Weight", + "description": "Maximum weight for this range (null for no upper bound).", + "minimum": 0 + }, + "expectedPercentage": { + "type": "number", + "title": "Expected Percentage", + "description": "Expected percentage of subjects in this weight range.", + "minimum": 0, + "maximum": 100 + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Display order of this range. Lower numbers appear first." + } + }, + "required": [ + "kitItemQuantities", + "fromWeight", + "toWeight", + "expectedPercentage", + "ordering" + ], + "additionalProperties": false + }, + "AgeBasedConfig": { + "type": "object", + "title": "Age-Based Configuration", + "description": "Configuration for age-based dosing.", + "properties": { + "ageUnit": { + "type": "string", + "title": "Age Unit", + "description": "Unit of age measurement.", + "enum": ["years", "months"] + }, + "ranges": { + "type": "object", + "title": "Age Ranges", + "description": "Map of range IDs to age ranges for kit assignment. Use ordering property to maintain display order.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/AgeRange" + } + }, + "additionalProperties": false + } + }, + "required": ["ageUnit", "ranges"], + "additionalProperties": false + }, + "AgeRange": { + "type": "object", + "title": "Age Range", + "description": "Age range configuration for dosing.", + "properties": { + "kitItemQuantities": { + "type": "object", + "title": "Kit Item Quantities", + "description": "Mapping of kit item IDs to quantities consumed per dose for subjects in THIS age range. Each value represents the number of units (e.g., tablets) of that item required for a single dose. Different age ranges can specify different quantities for the same item.", + "patternProperties": { + ".*": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "fromAge": { + "type": ["number", "null"], + "title": "From Age", + "description": "Minimum age for this range (null for no lower bound).", + "minimum": 0 + }, + "toAge": { + "type": ["number", "null"], + "title": "To Age", + "description": "Maximum age for this range (null for no upper bound).", + "minimum": 0 + }, + "expectedPercentage": { + "type": "number", + "title": "Expected Percentage", + "description": "Expected percentage of subjects in this age range.", + "minimum": 0, + "maximum": 100 + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Display order of this range. Lower numbers appear first." + } + }, + "required": [ + "kitItemQuantities", + "fromAge", + "toAge", + "expectedPercentage", + "ordering" + ], + "additionalProperties": false + }, + "TreatmentPeriod": { + "type": "object", + "title": "Treatment Period", + "description": "Treatment period in a dosing regimen sequence.", + "properties": { + "periodType": { + "type": "string", + "const": "treatment", + "title": "Period Type", + "description": "Discriminator identifying this as a treatment period." + }, + "dosingRegimenId": { + "type": "string", + "title": "Dosing Regimen ID", + "description": "ID of the dosing regimen used during this treatment period." + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Order position of this period in the sequence." + } + }, + "required": ["periodType", "dosingRegimenId", "ordering"], + "additionalProperties": false + }, + "WashoutPeriod": { + "type": "object", + "title": "Washout Period", + "description": "Washout period (no dosing) in a dosing regimen sequence.", + "properties": { + "periodType": { + "type": "string", + "const": "washout", + "title": "Period Type", + "description": "Discriminator identifying this as a washout period." + }, + "duration": { + "type": "number", + "title": "Duration", + "description": "Duration of the washout period.", + "exclusiveMinimum": 0 + }, + "durationUnit": { + "type": "string", + "title": "Duration Unit", + "description": "Unit of washout duration.", + "enum": ["days", "weeks", "months", "years"] + }, + "ordering": { + "type": "number", + "title": "Ordering", + "description": "Order position of this period in the sequence." + } + }, + "required": ["periodType", "duration", "durationUnit", "ordering"], + "additionalProperties": false + }, + "SequencePeriod": { + "oneOf": [ + { + "$ref": "#/definitions/TreatmentPeriod" + }, + { + "$ref": "#/definitions/WashoutPeriod" + } + ] + }, + "SequencePeriodMap": { + "type": "object", + "title": "Sequence Periods", + "description": "Ordered sequence of treatment and washout periods, keyed by unique period ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/SequencePeriod" + } + }, + "additionalProperties": false, + "minProperties": 1 + }, + "TreatmentArm": { + "type": "object", + "title": "Treatment Arm", + "description": "Treatment arm configuration from wizard step 5.", + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Name of the treatment arm." + }, + "allocationPercentage": { + "type": "number", + "title": "Allocation Percentage", + "description": "Percentage of subjects allocated to this arm.", + "minimum": 0, + "maximum": 100 + }, + "dosingRegimenSequence": { + "$ref": "#/definitions/SequencePeriodMap", + "title": "Dosing Regimen Sequence", + "description": "Sequence of treatment and washout periods for this treatment arm." + } + }, + "required": ["name", "allocationPercentage", "dosingRegimenSequence"], + "additionalProperties": false + }, + "SubjectFlow": { + "type": "object", + "title": "Subject Flow", + "description": "Site supply and region configuration from wizard step 6.", + "properties": { + "regions": { + "type": "object", + "title": "Countries", + "description": "Region-specific site configuration, keyed by ID.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/RegionConfig" + } + }, + "additionalProperties": false + } + }, + "required": ["regions"], + "additionalProperties": false + }, + "RegionConfig": { + "oneOf": [ + { + "$ref": "#/definitions/RegionContainer" + }, + { + "$ref": "#/definitions/RegionLeaf" + } + ] + }, + "RegionContainer": { + "type": "object", + "title": "Region Container", + "description": "Container node for grouping regions. Has subregions but no sites.", + "properties": { + "nodeType": { + "type": "string", + "const": "container", + "title": "Node Type", + "description": "Discriminator identifying this as a container node." + }, + "regionName": { + "type": "string", + "title": "Region Name", + "description": "Name of the region container." + }, + "subregions": { + "type": "object", + "title": "Subregions", + "description": "Child regions within this container.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/RegionConfig" + } + }, + "additionalProperties": false + }, + "activationStartDate": { + "type": ["string", "null"], + "format": "date", + "title": "Activation Start Date", + "description": "Default activation start date for child regions. Null means no default." + }, + "screenRate": { + "type": ["number", "null"], + "title": "Screen Rate", + "description": "Default screen rate for child regions. Null means no default.", + "exclusiveMinimum": 0 + }, + "siteActivationRate": { + "type": ["number", "null"], + "title": "Site Activation Rate", + "description": "Default site activation rate for child regions. Null means no default.", + "exclusiveMinimum": 0 + }, + "maxEnrollmentPerSite": { + "type": ["number", "null"], + "title": "Maximum Enrollment Per Site", + "description": "Default max enrollment per site for child regions. Null means no default.", + "minimum": 0 + }, + "siteSeeding": { + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + } + } + ], + "title": "Site Seeding", + "description": "Default site seeding quantity per kit for child regions. Map of kitId to quantity, or null to inherit." + } + }, + "required": ["nodeType", "regionName", "subregions"], + "additionalProperties": false + }, + "RegionLeaf": { + "type": "object", + "title": "Region Leaf", + "description": "Leaf node representing an operational region with sites.", + "properties": { + "nodeType": { + "type": "string", + "const": "region", + "title": "Node Type", + "description": "Discriminator identifying this as a leaf region node." + }, + "regionName": { + "type": "string", + "title": "Region Name", + "description": "Name of the region." + }, + "numberOfSites": { + "type": "integer", + "title": "Number of Sites", + "description": "Total number of sites in this region.", + "minimum": 1 + }, + "activationStartDate": { + "type": ["string", "null"], + "format": "date", + "title": "Activation Start Date", + "description": "Date when site activation begins. Null inherits from parent container." + }, + "screenRate": { + "type": ["number", "null"], + "title": "Screen Rate", + "description": "Number of subjects screened per site per month. Null inherits from parent container.", + "exclusiveMinimum": 0 + }, + "siteActivationRate": { + "type": ["number", "null"], + "title": "Site Activation Rate", + "description": "Number of sites activated per month. Null inherits from parent container.", + "exclusiveMinimum": 0 + }, + "maxEnrollmentPerSite": { + "type": ["number", "null"], + "title": "Maximum Enrollment Per Site", + "description": "Maximum number of patients that can be enrolled per site. Null for unlimited or inherited.", + "minimum": 0 + }, + "siteSeeding": { + "oneOf": [ + { + "type": "null" + }, + { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0 + } + } + ], + "title": "Site Seeding", + "description": "Site seeding quantity per kit. Map of kitId to quantity, or null to inherit from parent." + } + }, + "required": ["nodeType", "regionName", "numberOfSites"], + "additionalProperties": false + }, + "RegionForecast": { + "type": "object", + "title": "Region Forecast", + "description": "Atomic monthly forecast data for a single region. All values are monthly (not cumulative). UI computes cumulative views.", + "properties": { + "sites": { + "$ref": "#/definitions/PositiveDateMap", + "title": "Sites", + "description": "Monthly count of sites opened this month." + }, + "subjectsScreened": { + "$ref": "#/definitions/PositiveDateMap", + "title": "Subjects Screened", + "description": "Monthly count of subjects screened this month." + }, + "subjectsScreenedOut": { + "$ref": "#/definitions/PositiveDateMap", + "title": "Subjects Screened Out", + "description": "Monthly count of subjects who failed screening this month." + }, + "subjectsEnrolled": { + "$ref": "#/definitions/ByArmDateMap", + "title": "Subjects Enrolled", + "description": "Monthly subjects enrolled, broken down by treatment arm." + }, + "subjectsActive": { + "$ref": "#/definitions/ByArmDateMap", + "title": "Subjects Active", + "description": "Monthly change in active subjects (new active this month), broken down by treatment arm." + }, + "subjectsCompleted": { + "$ref": "#/definitions/ByArmDateMap", + "title": "Subjects Completed", + "description": "Monthly subjects who completed treatment, broken down by treatment arm." + }, + "subjectsDroppedOut": { + "$ref": "#/definitions/ByArmDateMap", + "title": "Subjects Dropped Out", + "description": "Monthly subjects who dropped out, broken down by treatment arm." + }, + "kitDemand": { + "$ref": "#/definitions/ByArmSequenceKitDateMap", + "title": "Kit Demand", + "description": "Monthly kit demand (whole kits rounded up), broken down by treatment arm and kit ID. Use this for supply planning - it accounts for buffer/waste in partially-used bottles." + }, + "kitItemDemand": { + "$ref": "#/definitions/ByArmSequenceKitItemDateMap", + "title": "Kit Item Demand", + "description": "Monthly kit item consumption (what patients actually receive), broken down by treatment arm and item ID. Displayed as 'Dosing' in the UI. Note: This is consumption, not supply demand - it does not include buffer/waste from partially-used bottles. For supply planning, use kitDemand." + }, + "siteSeedingKitDemand": { + "$ref": "#/definitions/ByKitDateMap", + "title": "Site Seeding Kit Demand", + "description": "Site seeding kit demand - kits shipped when sites activate (not treatment-driven). Keyed by kit ID." + } + }, + "required": [ + "sites", + "subjectsScreened", + "subjectsScreenedOut", + "subjectsEnrolled", + "subjectsActive", + "subjectsCompleted", + "subjectsDroppedOut", + "kitDemand", + "kitItemDemand", + "siteSeedingKitDemand" + ], + "additionalProperties": false + }, + "ClinicalDemandCalculatedForecast": { + "type": "object", + "title": "Clinical Demand Calculated Forecast", + "description": "Atomic monthly forecast data. Contains per-region data only. UI computes global totals and cumulative views.", + "properties": { + "byRegion": { + "type": "object", + "title": "By Region", + "description": "Region-specific forecast data keyed by region ID.", + "additionalProperties": { + "$ref": "#/definitions/RegionForecast" + } + } + }, + "required": ["byRegion"], + "additionalProperties": false + }, + "PositiveDateMap": { + "type": "object", + "title": "Positive Date Map", + "description": "Mapping of dates to positive numerical values.", + "patternProperties": { + "^\\d{4}-(0[1-9]|1[0-2])-01$": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "ByArmDateMap": { + "type": "object", + "title": "By Arm Date Map", + "description": "Mapping of treatment arm IDs to date-value maps. Each arm ID maps to a PositiveDateMap.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/PositiveDateMap" + } + }, + "additionalProperties": false + }, + "KitDemandEntry": { + "type": "object", + "title": "Kit Demand Entry", + "description": "Kit demand with placeboOf tagging for active/placebo separation.", + "properties": { + "demand": { + "$ref": "#/definitions/PositiveDateMap", + "description": "Monthly kit demand values keyed by YYYY-MM-DD date." + }, + "placeboOf": { + "type": ["string", "null"], + "description": "Regimen ID this is placebo of, or null if active." + } + }, + "required": ["demand", "placeboOf"], + "additionalProperties": false + }, + "KitItemDemandEntry": { + "type": "object", + "title": "Kit Item Demand Entry", + "description": "Kit item consumption entry with placeboOf tagging for active/placebo separation. Represents what patients actually receive, not supply demand.", + "properties": { + "demand": { + "$ref": "#/definitions/PositiveDateMap", + "description": "Monthly kit item demand values keyed by YYYY-MM-DD date." + }, + "placeboOf": { + "type": ["string", "null"], + "description": "Regimen ID this is placebo of, or null if active." + } + }, + "required": ["demand", "placeboOf"], + "additionalProperties": false + }, + "ByArmSequenceKitDateMap": { + "type": "object", + "title": "By Arm Sequence Kit Date Map", + "description": "Mapping of treatment arm IDs to sequence periods to kit demand. Structure: arm → sequenceId → kit → KitDemandEntry. The sequence ID matches keys in dosingRegimenSequence.", + "patternProperties": { + ".*": { + "type": "object", + "description": "Mapping of sequence period IDs to kit demand for this arm.", + "patternProperties": { + ".*": { + "type": "object", + "description": "Mapping of kit IDs to KitDemandEntry for this sequence period.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/KitDemandEntry" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "ByArmSequenceKitItemDateMap": { + "type": "object", + "title": "By Arm Sequence Kit Item Date Map", + "description": "Mapping of treatment arm IDs to sequence periods to kit item consumption. Structure: arm → sequenceId → item → KitItemDemandEntry. The sequence ID matches keys in dosingRegimenSequence. Displayed as 'Dosing' in the UI.", + "patternProperties": { + ".*": { + "type": "object", + "description": "Mapping of sequence period IDs to kit item demand for this arm.", + "patternProperties": { + ".*": { + "type": "object", + "description": "Mapping of item IDs to KitItemDemandEntry for this sequence period.", + "patternProperties": { + ".*": { + "$ref": "#/definitions/KitItemDemandEntry" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "ByKitDateMap": { + "type": "object", + "title": "By Kit Date Map", + "description": "Mapping of kit IDs to date-value maps for site-level kit demand (not per-arm).", + "patternProperties": { + ".*": { + "$ref": "#/definitions/PositiveDateMap" + } + }, + "additionalProperties": false + }, + "ClinicalDemandActuals": { + "type": "object", + "title": "Clinical Demand Actuals", + "description": "Actual enrollment data entered by users to reconcile with forecast.", + "properties": { + "enrollment": { + "type": "object", + "title": "Enrollment Actuals", + "description": "Actual enrollment by region and month.", + "patternProperties": { + ".*": { + "type": "object", + "patternProperties": { + ".*": { + "type": "object", + "properties": { + "total": { + "type": "number", + "title": "Total Enrolled", + "description": "Total subjects enrolled for this region and month.", + "minimum": 0 + }, + "byArm": { + "type": "object", + "title": "Enrollment by Arm", + "description": "Enrollment count per treatment arm.", + "patternProperties": { + ".*": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + } + }, + "required": ["total", "byArm"], + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "sites": { + "type": "object", + "title": "Sites Actuals", + "description": "Actual site counts by region and month.", + "patternProperties": { + ".*": { + "type": "object", + "patternProperties": { + ".*": { + "type": "number", + "minimum": 0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "notes": { + "type": "object", + "title": "Actuals Notes", + "description": "Explanatory notes for enrollment actuals by region and month.", + "patternProperties": { + ".*": { + "type": "object", + "patternProperties": { + ".*": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "siteNotes": { + "type": "object", + "title": "Site Actuals Notes", + "description": "Explanatory notes for site activation actuals by region and month.", + "patternProperties": { + ".*": { + "type": "object", + "patternProperties": { + ".*": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + }, + "required": ["enrollment", "sites", "notes", "siteNotes"], + "additionalProperties": false + } + } +} diff --git a/src/test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast.json b/src/test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast.json new file mode 100644 index 00000000000..fec506ca99e --- /dev/null +++ b/src/test/abc-clinical-demand-forecast-1.0.0/abc-clinical-demand-forecast.json @@ -0,0 +1,237 @@ +{ + "$schema": "https://json.schemastore.org/abc-clinical-demand-forecast-1.0.0.json", + "analytics": { + "items": [], + "layouts": [], + "tabs": [ + { + "id": "1780000000001", + "name": "Overview", + "ordering": 0 + } + ] + }, + "clinicalDemandCalculatedForecast": { + "byRegion": { + "region-1": { + "kitDemand": { + "arm-1780000000030": { + "period-1768534785069-6trwchxnu": { + "1780000001000": { + "demand": { + "2026-01-01": 1, + "2026-02-01": 0 + }, + "placeboOf": null + } + } + }, + "arm-1780000000040": { + "period-1768534785069-1np60aauq": { + "1780000001000": { + "demand": { + "2026-01-01": 1, + "2026-02-01": 0 + }, + "placeboOf": "regimen-1780000000010" + } + } + } + }, + "kitItemDemand": { + "arm-1780000000030": { + "period-1768534785069-6trwchxnu": { + "1780000000100": { + "demand": { + "2026-01-01": 10, + "2026-02-01": 0 + }, + "placeboOf": null + } + } + }, + "arm-1780000000040": { + "period-1768534785069-1np60aauq": { + "1780000000100": { + "demand": { + "2026-01-01": 10, + "2026-02-01": 0 + }, + "placeboOf": "regimen-1780000000010" + } + } + } + }, + "siteSeedingKitDemand": { + "1780000001000": { + "2026-01-01": 0, + "2026-02-01": 0 + } + }, + "sites": { + "2026-01-01": 1, + "2026-02-01": 0 + }, + "subjectsActive": { + "arm-1780000000030": { + "2026-01-01": 1, + "2026-02-01": 0 + }, + "arm-1780000000040": { + "2026-01-01": 1, + "2026-02-01": 0 + } + }, + "subjectsCompleted": { + "arm-1780000000030": { + "2026-01-01": 0, + "2026-02-01": 1 + }, + "arm-1780000000040": { + "2026-01-01": 0, + "2026-02-01": 1 + } + }, + "subjectsDroppedOut": { + "arm-1780000000030": { + "2026-01-01": 0, + "2026-02-01": 0 + }, + "arm-1780000000040": { + "2026-01-01": 0, + "2026-02-01": 0 + } + }, + "subjectsEnrolled": { + "arm-1780000000030": { + "2026-01-01": 1, + "2026-02-01": 0 + }, + "arm-1780000000040": { + "2026-01-01": 1, + "2026-02-01": 0 + } + }, + "subjectsScreened": { + "2026-01-01": 2, + "2026-02-01": 0 + }, + "subjectsScreenedOut": { + "2026-01-01": 0, + "2026-02-01": 0 + } + } + } + }, + "clinicalDemandForecastConfiguration": { + "actuals": { + "enrollment": {}, + "notes": {}, + "siteNotes": {}, + "sites": {} + }, + "dosingRegimens": { + "regimen-1780000000010": { + "description": "Active treatment with 10 mg tablets", + "dosingRegimenDefinition": { + "ageBasedConfig": null, + "doseEscalationConfig": null, + "dosingFrequency": "once_daily_qd", + "fixedConfig": { + "kitItemQuantities": { + "1780000000100": 1 + } + }, + "isPlacebo": false, + "treatmentDuration": 10, + "treatmentDurationUnit": "days", + "weightBasedConfig": null + }, + "name": "Fixed 10 mg" + }, + "regimen-1780000000020": { + "description": "Placebo treatment", + "dosingRegimenDefinition": { + "isPlacebo": true, + "placeboOf": "regimen-1780000000010" + }, + "name": "Placebo" + } + }, + "enrollment": { + "attritionRate": 0, + "screenFailureRate": 0, + "targetCompleted": 2 + }, + "kitConfiguration": { + "1780000001000": { + "items": { + "1780000000101": { + "children": { + "1780000000100": { + "deliveryForm": "tablet", + "dosage": 10, + "name": "Tablet", + "nodeType": "item", + "ordering": 0, + "quantity": 10, + "units": "mg" + } + }, + "deliveryForm": "bottle", + "name": "Bottle", + "nodeType": "container", + "ordering": 0 + } + }, + "name": "Memorax Kit" + } + }, + "studyOverview": { + "protocolSummary": "Simplest blinded actuals test: 2 subjects, 2 arms at 50/50 split", + "studyName": "Clinical Demand Forecast Blinded Actuals Entry Simplest Test", + "studyPhase": "phase_i", + "therapeuticArea": "CNS/Neurology" + }, + "subjectFlow": { + "regions": { + "region-1": { + "activationStartDate": "2026-01-01", + "maxEnrollmentPerSite": null, + "nodeType": "region", + "numberOfSites": 1, + "regionName": "USA", + "screenRate": 2, + "siteActivationRate": 1, + "siteSeeding": null + } + } + }, + "treatmentArms": { + "arm-1780000000030": { + "allocationPercentage": 0.5, + "dosingRegimenSequence": { + "period-1768534785069-6trwchxnu": { + "dosingRegimenId": "regimen-1780000000010", + "ordering": 0, + "periodType": "treatment" + } + }, + "name": "Memorax" + }, + "arm-1780000000040": { + "allocationPercentage": 0.5, + "dosingRegimenSequence": { + "period-1768534785069-1np60aauq": { + "dosingRegimenId": "regimen-1780000000020", + "ordering": 0, + "periodType": "treatment" + } + }, + "name": "Placebo" + } + }, + "trialDesign": "parallel" + }, + "planNotes": "{\"blocks\":[{\"key\":\"a1\",\"text\":\"TEST PURPOSE: Validates blinded actuals entry with end date change.\",\"type\":\"header-three\",\"depth\":0,\"inlineStyleRanges\":[{\"offset\":0,\"length\":13,\"style\":\"BOLD\"}],\"entityRanges\":[],\"data\":{}},{\"key\":\"a2\",\"text\":\"\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a3\",\"text\":\"CONFIGURATION:\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[{\"offset\":0,\"length\":14,\"style\":\"BOLD\"}],\"entityRanges\":[],\"data\":{}},{\"key\":\"a4\",\"text\":\"Two treatment arms: 50% Memorax (active), 50% Placebo\",\"type\":\"unordered-list-item\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a5\",\"text\":\"Target: 2 subjects, enrollment rate: 2/month\",\"type\":\"unordered-list-item\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a6\",\"text\":\"Initial forecast: Completes in January 2026\",\"type\":\"unordered-list-item\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a7\",\"text\":\"\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a8\",\"text\":\"BLINDED ACTUALS TEST:\",\"type\":\"unstyled\",\"depth\":0,\"inlineStyleRanges\":[{\"offset\":0,\"length\":21,\"style\":\"BOLD\"}],\"entityRanges\":[],\"data\":{}},{\"key\":\"a9\",\"text\":\"Enter 1 subject actual for January (blinded entry)\",\"type\":\"unordered-list-item\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a10\",\"text\":\"Allocated to Memorax (first treatment arm in sorted order)\",\"type\":\"unordered-list-item\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}},{\"key\":\"a11\",\"text\":\"After re-forecast: End date extends to February 2026\",\"type\":\"unordered-list-item\",\"depth\":0,\"inlineStyleRanges\":[],\"entityRanges\":[],\"data\":{}}],\"entityMap\":{}}" +} From bd741961b512e6dd6345d09a24152ab3144538db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kriszti=C3=A1n=20G=C3=B6drei?= Date: Tue, 3 Mar 2026 19:46:14 +0100 Subject: [PATCH 3/3] Update step.yml and bitrise.yml json schemas (#5433) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update from the upstream repo (#7) * relocate incoming files definition and rename attributesDesc to attributes in tasks * remove Duration and add ability to have loader specified in the connection * Support connections specific to load and/or transforms * Improve expectations * Update expectations in load section also * Code spell fix * Add DATAFRAME option * Add new attribute duckdbExtensions * fix typo * apply prettier * Add support for database sync * fix typo * Add ability to externalize macros and types folders * add bento stream configuration file schema (#5293) * add bento stream configuration file schema Signed-off-by: Jem Davies * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Jem Davies Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(renovate): add previous major versions' schemas + global self-hosted config (#5294) * feat(renovate): introduce "global" JSON schema As part of Renovate 41.x we introduced the separation of "repo" and "global" configuration into separate JSON Schema documents. * feat(renovate): add previous major versions' schemas As noted in #5285, it would be convenient to have the previous versions of Renovate JSON Schema files, for use after the major version is bumped and no longer supported. As a starting point we can look at the major versions in use in 2025, retrieving them from the `docs.tgz` on the last release in a given major series. This also requires we: - add the `$id` and `id` fields - run `prettier` on the schemas - make sure validation doesn't try running in `strict` Ajv mode - make sure validation ignores custom properties - make sure spell check doesn't flag partial regexes like `|[Cc]ontainer` as a typo Closes #5285. * feat: add lefthook jsonc catalog file matches (#5295) Refs https://github.com/evilmartians/lefthook/pull/1274 * feat: add Awesome Repositories schema (self-hosted) (#5296) * Add artifact-metadata property to github-workflow schema (#5292) The new [`artifact-metadata` granular permission](https://github.blog/changelog/2026-01-13-new-fine-grained-permission-for-artifact-metadata-is-now-generally-available/) is now generally available. * Add `buf.lock` support (#5297) * Add `buf.lock` support Ref: https://buf.build/docs/configuration/v2/buf-lock * Fix lint * Update ty's JSON schema (#5299) This updates ty's JSON schema to [fc1478bd96387a0ce5fe077cce0b316a798a641d](https://github.com/astral-sh/ty/commit/fc1478bd96387a0ce5fe077cce0b316a798a641d) * feat: add new properties and descriptions to Traefik v3 JSON schema and example (#5302) * add pgxgen configuration file schema (#5303) * update dotnet download to cdn endpoint * feat(rumdl): host schema locally for direct URL access Adds the rumdl schema file to the repository so it can be accessed directly at https://json.schemastore.org/rumdl.json Previously, the catalog entry pointed to an external GitHub raw URL, which meant the direct SchemaStore URL returned 404. This change enables users to use $schema references and validators that don't consult the catalog. Changes: - Add src/schemas/json/rumdl.json - Update catalog.json URL to use local schema * feat: specify type of array items * Update Claude Code settings schema with missing settings and fixes (#5300) Co-authored-by: domdomegg * feat: add Hugo import version property * add codex config.toml schema * Add editorconfig for web and packages .config (#5311) * Introduce dark mode (#5313) * Introduce dark mode * Add a color-scheme meta tag to declare light and dark schemes, making use of browser defaults as well * Adjust site.css for dark mode coloring * Use variables and `light-dark()` instead of media queries and multiple blocks and overrides * 'bg' for background, 'fg' for foreground * Numbered color tiers and named categories * Use a set of subjectively sensible and coherent dark mode colors * Keep header coloring style, no inversion of fg and bg Note: The JSON and GitHub images have ugly kerning around the edges presumably because of transparency and quality. If it's a requirement then I can look into that for this PR. Otherwise, maybe I will take a look afterwards. Still, even with the kerning, I would prefer using a dark theme. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Update Claude Code settings schema for v2.1.19 (#5314) Co-authored-by: domdomegg * Replace API image with JSON Schema logo (#5317) Replace stylized JSON image, which is not the official JSON logo, with the JSON Schema logo. Image source: Official JSON Schema website sources at https://github.com/json-schema-org/website/blob/fd76cd790cc68928a5eadaa14a76dca28f70bea5/public/logo-blue.svg The text block starts with “The JSON API contains a list of JSON Schema files for known JSON file formats.”. Our API provides JSON Schema, so using a JSON schema logo seems appropriate, certainly more so than using only the official JSON logo. Positive consequences: * Scalable and high-dpi-capable SVG instead of PNG * Fixes dark scheme visual transparency edge rendering artifacts (consequence of dark mode introduced in #5313) * Drop editorconfig EOL configuration (#5316) The `.gitattributes` configures `text=auto`. This means text files will use, unless already committed differently in the repo, auto-convert line endings. My VS created mixed line endings even when duplicating existing lines. For now, revert the EOL configuration to restore previous behavior consistent to the gitattributes configuration. IMO, it would be preferable to use intentional EOL configuration without depending on auto-conversion, which has complex conditions and is error-prone. But this change does not do that (yet). * Update kya.json (#5315) add KYA add KYA Update kya.json Update kya.json removed punctuation Update catalog.json Update catalog.json Update kya.json * Improve sponsor image, fix dark scheme visual artifacts (#5318) Source image is https://github.githubassets.com/assets/mona-e50f14d05e4b.png from GitHub Sponsors https://github.com/sponsors/accounts It's the same image like before. Resized with GIMP. Results in a bit different/more vibrant coloring, and the dark scheme edge issue fixed. * add Espanso schemas (#5319) * add espanso yaml schemas * fix match.yml description * [pre-commit.ci] pre-commit autoupdate (#5320) updates: - [github.com/rbubley/mirrors-prettier: v3.7.4 → v3.8.1](https://github.com/rbubley/mirrors-prettier/compare/v3.7.4...v3.8.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(renovate): add "inherited" config (#5321) Now it's available as its own schema, it'd be good to store a copy here, too. * Add Applicant Profile Protocol (APP) schema (#5322) - Schema URL: https://app-protocol.org/schema/app-1.0.json - File pattern: *.app.json - Description: Structured JSON format for professional profiles, resumes, and CVs The Applicant Profile Protocol (APP) is an open, JSON-based standard for representing professional profiles with comprehensive support for skills, experience, education, certifications, projects, and languages. Features: - JSON Schema validation (draft 2020-12) - Export to JSON Resume, Europass XML, HR-XML - Semantic layer support via JSON-LD - Protocol version management - Comprehensive field definitions Documentation: https://app-protocol.org/spec/1.0 Repository: https://github.com/caglarorhan/Applicant-Profile-Protocol npm package: applicant-profile-protocol * Add AWS Amplify Console build schema (amplify.json), positive test, and catalog entry. (#5323) * feat: add Renovate 42's JSON Schema (#5324) Now we've released Renovate 43, we'll store the 42.95.1 JSON schema as an older version for folks to access. * fix(tsconfig): Allow "module" Node20 (capital N) (#5326) * Add OpenSRM (Open Service Reliability Manifest) schema (#5327) OpenSRM is an open specification for declaring service reliability requirements as code. It enables shift-left reliability by defining SLOs, contracts, and dependencies before deployment. - Schema: src/schemas/json/opensrm.json (draft-07) - 8 positive tests, 5 negative tests - Added to ajvNotStrictMode (uses anyOf + required patterns) Co-authored-by: Claude Opus 4.5 * Replace octocat image png -> svg (#5329) * Update Claude Code settings schema for v2.1.29 * Add hostPattern marketplace tests for Claude Code settings * Format and refine Claude Code settings tests * youtrack-app. Add a new endpoint PROJECT_TAB (#5328) * Add Claude Code Keybindings schema (#5325) * Add Claude Code Keybindings schema Add JSON Schema for Claude Code's keybindings.json configuration file (~/.claude/keybindings.json), which allows users to customize keyboard shortcuts in the Claude Code CLI. The schema validates: - Binding blocks scoped to UI contexts (Global, Chat, etc.) - Built-in action references (app:interrupt, chat:submit, etc.) - Command bindings (command:commit, command:help, etc.) - Null values for unbinding default shortcuts - Chord keystroke patterns (e.g., ctrl+k ctrl+s) Includes 6 positive test files and 7 negative test files. Documentation: https://code.claude.com/docs/en/keybindings * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add claude-code-keybindings to CODEOWNERS --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add dataset_triggering options and improve documentation * update description * Fix typo * feat(rumdl): update schema to v0.1.10 (#5340) * feat(rumdl): update schema to v0.1.10 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: github-actions[bot] Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add pitcms schema (#5342) Add JSON schema for pitcms, a Git-based headless CMS. Schema is self-hosted at https://pitcms.net/schema/pitcms.schema.json * Update ruff's JSON schema (#5343) This updates ruff's JSON schema to [ce5f7b6127a5d684e96fd0f8e387f73c41c7a1b0](https://github.com/astral-sh/ruff/commit/ce5f7b6127a5d684e96fd0f8e387f73c41c7a1b0) * Add basedpyright schema * Update vCluster config schema URL * Add schema for `prek` * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * feat(rumdl): update schema to v0.1.13 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * snowflake config: update authenticator variants and subsequent WIF authentication properties see https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update ty's JSON schema This updates ty's JSON schema to [044af7fda21189c69a489362f451ebd600ef460a](https://github.com/astral-sh/ty/commit/044af7fda21189c69a489362f451ebd600ef460a) * Add bricks schema (#5351) * Add `auditLevel` to pnpm-workspace.json (#5352) Co-authored-by: btea * feat(claude-code-settings): sync to Claude Code v2.1.29 (#5337) Co-authored-by: domdomegg * Add missing octocat.svg Regression from c28c44d8 through PR #5329 where the old png was replaced, but the new svg was missing. * Mail Servers Configuration # Add Mail Servers Configuration JSON Schema ## Description Adds a JSON schema for storing mail server configurations for different domains. The schema supports flexible configuration of POP3, IMAP, and SMTP servers with strict validation rules. ## Changes ### New Schema - `src/schemas/json/mail-servers-config.json` - Main configuration schema for mail servers ### Tests - **Positive Tests** (`src/test/mail-servers-config/`): - `valid-complete.json` - Full configuration with POP3, IMAP, and SMTP - `valid-minimal-imap-smtp.json` - IMAP and SMTP only - `valid-pop-only.json` - POP3 only - `valid-multiple-protocols.json` - Various protocol combinations for different domains - `valid-default-ports.json` - Validation with default port values - **Negative Tests** (`src/negative_test/mail-servers-config/`): - `invalid-port-range.json` - Ports outside 1-65535 range - `extra-property-domain.json` - Additional properties at domain level - `extra-property-protocol.json` - Additional properties in protocol objects - `empty-object.json` - Empty object (violates minProperties: 1) - `invalid-hostname.json` - Invalid hostname format - `missing-host.json` - Missing required host field - `missing-port.json` - Missing required port field - `wrong-type.json` - Incorrect data types ### Catalog Entry Added to `src/api/json/catalog.json`: ```json { "name": "Mail Servers Configuration", "description": "Schema for storing mail server configurations", "fileMatch": [ "mail-servers-config.json", "mail-servers-config.jsonc", "mail-servers-config.json5", "*.mail-servers-config.json", "*.mail-servers-config.jsonc", "*.mail-servers-config.json5", "**/mail-servers-config.json", "**/mail-servers-config.jsonc", "**/mail-servers-config.json5" ], "url": "https://www.schemastore.org/mail-servers-config.json" } ``` ## Schema Features ### Configuration Flexibility 1. **Optional Protocols:** Each domain can contain any combination of POP3, IMAP, and SMTP protocols 2. **Strict Protocol Validation:** Each protocol requires both host and port fields 3. **No Additional Properties:** Extra properties are disallowed at both domain and protocol levels ### Data Validation - **Ports:** Restricted to valid range 1-65535 - **Hostname:** Validated against hostname format - **Default Values:** Standard ports are suggested: - POP3: 995 - IMAP: 993 - SMTP: 587 - **Minimum One Domain:** At least one domain configuration is required (`minProperties: 1`) ## Typical Usage Example ```json { "gmail.com": { "imap": {"host": "imap.gmail.com", "port": 993}, "smtp": {"host": "smtp.gmail.com", "port": 587} }, "outlook.com": { "imap": {"host": "outlook.office365.com", "port": 993}, "smtp": {"host": "smtp.office365.com", "port": 587} } } ``` ## Validation - ✅ All tests pass validation with Ajv - ✅ Schema conforms to draft-07 specification - ✅ Compatible with strict mode - ✅ Comprehensive edge case coverage ## Potential Use Cases 1. **Email Client Configuration:** Storing settings for different email providers 2. **Mailbox Migration:** Describing source and destination mail servers 3. **Infrastructure Documentation:** Centralized storage of company mail server configurations 4. **Automation Scripts:** Use in scripts for automatic email client configuration ## Compatibility - Compatible with all JSON Schema validators supporting draft-07 - Supported in VS Code, IntelliJ IDEA, and other IDEs through SchemaStore - Can be used with `yaml-language-server` for YAML files ## Checklist - Schema follows draft-07 specification - Added both positive and negative test cases - All tests pass validation - Added catalog entry with appropriate fileMatch patterns - No breaking changes to existing schemas - Schema is compatible with strict mode * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * chore(deps): update ctfd.json schema for ctfd-setup v1.8.4 (#5360) Co-authored-by: pandatix * Update claude-code-settings.json: add TeammateIdle and TaskCompleted hooks (#5361) Co-authored-by: domdomegg * feat(claude-code-settings): sync to Claude Code v2.1.37 (#5354) Co-authored-by: domdomegg * [claude-code-settings] Add missing tool names to permissionRule pattern (#5363) Co-authored-by: domdomegg * Add ECA config json (#5356) * Add ECA config json * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Merge pull request #5358 from cjdcordeiro/patch-1 feat: add 'hint' property to chisel-slices schema * Added support for specmatic config v3 (#5362) * chore: deprecate formatter * Add Config Specmatic V3 schema * chore: update provides/consumes for v3 * Updated specmatic.yaml jsonschema with version 3 * Added v3 examples * Got jsonschema working with the simpler reffed and re-reffed examples * Changed some schema names of systemUnderTest schemas to improve symmetry with the corresponding dependency schema names * Updated specmatic schema and sample uber-v3 json file * added some negative examples for specmatic v3 schema * Updated the new specmatic schema and test files using prettier * Add telemetry flag for specmatic v2 config * Added missing hooks to the adapters schema * Added CODEOWNERS entries for the Specmatic team --------- Co-authored-by: vedubhat Co-authored-by: Yogesh Nikam <60032699+yogeshnikam671@users.noreply.github.com> Co-authored-by: Sufiyan Co-authored-by: Ketan Padegaonkar * Merge pull request #5364 from j178/prek Update schema for prek * fix(hatch): better support build hooks under tombi strict (#5365) * Merge pull request #5367 from djgoku/chore-switch-cirrus-yml-to-git-link chore: Switch `.cirrus.yml` from SchemaStore to github URL * Merge pull request #5369 from astral-sh/update-ty-8cec857182f4bc28bd8e103940341643162777f8 Update ty's JSON schema * Merge pull request #5366 from rvben/rumdl-schema-update feat(rumdl): update schema to v0.1.19 * Add version 10.0 of the AIO connector metadata schema (#5334) * Add new version of the aio connector metadata schema This new version adds support for specifying one or multiple supported action types for a management group action * 10 * mandatory action types * Require "destinations" field for any specified "event", "dataset" and/or "stream" * Update ruff's JSON schema (#5368) This updates ruff's JSON schema to [a2f11d239f91cf8daedb0764ec15fcfe29c5ae6d](https://github.com/astral-sh/ruff/commit/a2f11d239f91cf8daedb0764ec15fcfe29c5ae6d) * Add JSON Schema for metadata.json, used by Docker Desktop extensions. (#5221) * Add JSON Schema for metadata.json, used by Docker Desktop extensions. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove fileMatch for docker desktop extension metadata JSON * set metaschema URL for docker-extension-metadata to http:// --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(claude-code-settings): sync to Claude Code v2.1.42 (#5371) Co-authored-by: domdomegg * feat(rumdl): update schema to v0.1.22 (#5372) Co-authored-by: github-actions[bot] * Add oxfmt and oxlint (#5373) * Add oxfmt and oxlint * lint * Update youtrack-app.json with conditional 'showHeader' (#5374) Co-authored-by: skoch13 * feat(claude-code-settings): sync to Claude Code v2.1.47 (#5378) Co-authored-by: domdomegg * Update regex of poe.tasks (#5377) https://github.com/nat-n/poethepoet/blob/6a59da122d31d99fab02182b60105c033e7a312e/poethepoet/task/base.py#L24 * feature: 🐊Putout v42 (#5379) * Update timezone data using tzdb 2025c (#5380) * Update ruff's JSON schema (#5382) This updates ruff's JSON schema to [9d18ee9115f9cbb4c21478baa7c1fa2b46e0759c](https://github.com/astral-sh/ruff/commit/9d18ee9115f9cbb4c21478baa7c1fa2b46e0759c) * fix(schema):fixed linting issues in appsscript.json and asconfig-schema.json (#5386) Signed-off-by: Vaibhav mittal * schema: add Pantsbuild - 2.31.0 (#5387) * schema: add Pantsbuild - 2.31.0 * id * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(rumdl): update schema to v0.1.24 (#5388) Co-authored-by: github-actions[bot] * feat(claude-code-settings): add managed/enterprise settings fields (#5389) Co-authored-by: bogini * feat(claude-code-settings): improve test coverage (#5385) Co-authored-by: domdomegg * Add @ant-kurt as CODEOWNERS for claude-code-settings (#5390) Co-authored-by: ant-kurt <209710463+ant-kurt@users.noreply.github.com> * Update ty's JSON schema (#5391) * Add BMML (Business Model Markup Language) schema (#5301) Co-authored-by: Mathias Maisberger * feat: add opt-in test coverage analysis tool (#5383) Co-authored-by: Claude Opus 4.6 * maturin: add FeatureSpec for features field (#5395) * Update bamboo-spec's JSON schema (#5396) * feat(bamboo-spec): add YAML test files from Atlassian Docs The content was retrieved as is from docs (https://docs.atlassian.com/bamboo-specs-docs/{version}/specs.html?yaml#yaml-specs-reference). * feat(bamboo-spec): add YAML schema references to new test files, reformat them * feat(bamboo-spec): update JSON schema to draft-07 * feat(bamboo-spec): update JSON schema for compatibility with 12.1.2 * feat(bamboo-spec): add 12.1.2 features * fix(coverage): reduce false positives in negative test isolation check (#5398) The negative test isolation heuristic used name-based property matching but overwrote constraints when the same property name appeared at different schema depths (e.g., "source" as object at one level and string at another). This caused false wrong_type violations. Changes: - Union all types, patterns, and enum values per property name instead of overwriting with last-seen value - Infer types from anyOf/oneOf/allOf variants when no explicit type is declared on a property schema - Update heuristic note to advise manual verification of flagged files Co-authored-by: Claude Opus 4.6 * Update pubspec schema to support workspace and null types (#5399) * Update catalog.json for Upsun (#5400) add `config.yaml` to avoid messing up with Upsun fixed (formerly Platform.sh) config validation * Add new Serilog log-level "Off" (#5401) See github.com/nblumhardt/serilog/commit/9b92c29c282b9cc6a7bfb540c470e8417ae594e7 * ✨ feat(tox): add tox.toml JSON Schema to catalog (#5402) * ✨ feat(tox): add tox.toml JSON Schema IDEs using taplo or Even Better TOML had no schema validation for standalone tox.toml files. The catalog entry points to tox's canonical schema at raw.githubusercontent.com so updates flow through without requiring PRs here. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Issue #5403: Update MetricsHub connector json schema (#5404) - Included FileSource and EventLogSource in both metricshub.json and metricshub-connector.json. - Added tests for both cases. - Tested. * fix(schema): normalize volumes metadata and resolve linting issues in azure-containerapp-template.json (#5393) * fix(schema): normalize volumes metadata and remove trailing punctuation in azure-containerapp-template.json Signed-off-by: Vaibhav mittal * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Vaibhav mittal Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(schema): add Flatpak Builder manifest JSON schema (#5394) * feat(schema): add Flatpak Builder manifest JSON schema * feat(catalog): register Flatpak manifest schema with file match patterns * test(flatpak-manifest): add positive and negative validation cases * chore(validation): update schema validation configuration for Flatpak manifest * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix(flatpak-manifest): remove x-deprecated keyword, not valid in draft-07 Signed-off-by: Vaibhav mittal * fix(flatpak-manifest): fix typo transfered -> transferred Signed-off-by: Vaibhav mittal --------- Signed-off-by: Vaibhav mittal Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(claude-code-settings): sync to Claude Code v2.1.50 (#5397) Co-authored-by: domdomegg * Add bg-dependency-aware-stop-order parameter (#5333) * feat(rumdl): update schema to v0.1.28 (#5411) Co-authored-by: github-actions[bot] * feat: Add Docs MCP configuration schema (#5412) * feat: schemastore entry for docs mcp public release * chore: lower schema entry * Update tox JSON Schema to 4.46.2 (#5414) * Update tox JSON Schema to 4.46.3 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add Citrus test case schema (#5408) * Add Citrus test case schema fixes #5407 Signed-off-by: Aurélien Pupier * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Aurélien Pupier Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Update ruff's JSON schema (#5415) This updates ruff's JSON schema to [a62ba8c6e2bac0b899d90fd30a1b26c07aac44bb](https://github.com/astral-sh/ruff/commit/a62ba8c6e2bac0b899d90fd30a1b26c07aac44bb) * Add aio wasm graph schema 1.1.0 (#5416) * Add aio wasm graph schema 1.1.0 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix validation --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(dependabot-2.0): update schema to match current Dependabot features (#5381) Sync the dependabot-2.0.json schema with the current state of Dependabot's configuration options, adding missing features and fixing constraints to match the actual implementation. Changes: - Add pre-commit to package-ecosystem enum (beta ecosystem) dependabot/dependabot-core#2183 - Add goproxy-server to registry type enum https://github.blog/changelog/2025-09-09-go-private-registry-support-for-dependabot-now-generally-available dependabot/dependabot-core#12747 - Add OIDC and AWS CodeArtifact registry auth properties (tenant-id, client-id, jfrog-oidc-provider-name, identity-mapping-name, audience, aws-region, account-id, role-name, domain, domain-owner, registry) https://github.blog/changelog/2026-02-03-dependabot-now-supports-oidc-authentication - Add group-by property to groups definition https://github.blog/changelog/2024-03-28-dependabot-grouped-security-updates-generally-available - Add name property to update definition - Add update-types, dependency-type, and exclude-patterns properties to multi-ecosystem-group definition https://github.blog/changelog/2025-07-01-single-pull-request-for-dependabot-multi-ecosystem-support - Fix cooldown constraints to match implementation: minimum 1 (not 0) for default/major/minor days, maximum 90 for all day fields, maxItems 100 (not 150) for include/exclude https://github.blog/changelog/2025-07-01-dependabot-supports-configuration-of-a-minimum-package-age - Fix ignore versions to accept string or array (was array-only) - Replace inline timezone enum with $ref to base.json - Add positive tests for new features * fix: update URLs from 4lando to lando-community (#5418) Co-authored-by: Aaron Feledy * Add mockd.yaml schema (multi-protocol API mock server) (#5417) * Upgrade appsettings.json schema to draft-07 (#5419) * Upgrade appsettings.json schema to draft-07 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add schema for JReleaser 1.23.0 (#5422) * Add schema for JReleaser 1.23.0 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat(claude-code-settings): sync to Claude Code v2.1.63 (#5421) Co-authored-by: domdomegg * Added schema for text2confl configuration file (#5423) * Update tox JSON Schema to 4.47.0 (#5424) * Update tox JSON Schema to 4.47.0 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add 3 more `FormatStyle` values for `.clang-tidy` (#5425) * Add 3 more `FormatStyle` values for `.clang-tidy` The previous values were only the ones listed in the docs for clang-tidy itself, but it references to check clang-format for the actual values. Clang-format also supports `chromium`, `microsoft` and `gnu`. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Add missing options to Traefik v3 file provider schema (#5426) * Update ty's JSON schema (#5428) This updates ty's JSON schema to [2bd0252435a1ad19b91863f37beab60bb8e68a14](https://github.com/astral-sh/ty/commit/2bd0252435a1ad19b91863f37beab60bb8e68a14) --------- Signed-off-by: Jem Davies Signed-off-by: Vaibhav mittal Signed-off-by: Aurélien Pupier Co-authored-by: Hayssam Saleh Co-authored-by: Jem Davies <131159520+jem-davies@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jamie Tanna Co-authored-by: Ville Skyttä Co-authored-by: Pavel Bychko Co-authored-by: Shane Frasier Co-authored-by: Stefan VanBuren Co-authored-by: Micha Reiser Co-authored-by: Rene Nulsch <33263735+ReneNulschDE@users.noreply.github.com> Co-authored-by: sxwebdev Co-authored-by: leecow Co-authored-by: Ruben J. Jongejan Co-authored-by: Giancarlo Calderón Cárdenas Co-authored-by: Edwin Kofler Co-authored-by: Mitesh Ashar Co-authored-by: domdomegg Co-authored-by: Jordan GAZEAU Co-authored-by: Sayan Sisodiya Co-authored-by: Jan Klass Co-authored-by: Lars K.L. Co-authored-by: rosidae0 <82954131+rosidae@users.noreply.github.com> Co-authored-by: Jamie Tanna Co-authored-by: Çağlar ORHAN <401240+caglarorhan@users.noreply.github.com> Co-authored-by: Jose Sierra <165445418+Ktsierra@users.noreply.github.com> Co-authored-by: Tobbe Lundberg Co-authored-by: Rob Fox Co-authored-by: Claude Opus 4.5 Co-authored-by: Kang Hyojun Co-authored-by: Max Maximov Co-authored-by: Andrew Morrison Co-authored-by: github-actions[bot] Co-authored-by: yuto <43196286+yuto343@users.noreply.github.com> Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com> Co-authored-by: Sean McCollum Co-authored-by: Johannes Frey Co-authored-by: Jo <10510431+j178@users.noreply.github.com> Co-authored-by: Yoav Yanilov Co-authored-by: Charlie Marsh Co-authored-by: Yevhenii Tiutiunnyk Co-authored-by: btea <2356281422@qq.com> Co-authored-by: btea Co-authored-by: Маг Ильяс DOMA Co-authored-by: ctfer-io-bot <160312728+ctfer-io-bot@users.noreply.github.com> Co-authored-by: pandatix Co-authored-by: Jonathan COURTY <139225837+Johntycour@users.noreply.github.com> Co-authored-by: adam jones Co-authored-by: Eric Dallo Co-authored-by: Cristovao Cordeiro Co-authored-by: Joel Rosario Co-authored-by: vedubhat Co-authored-by: Yogesh Nikam <60032699+yogeshnikam671@users.noreply.github.com> Co-authored-by: Sufiyan Co-authored-by: Ketan Padegaonkar Co-authored-by: CEnnis91 Co-authored-by: Jonathan Otsuka <105506+djgoku@users.noreply.github.com> Co-authored-by: David Peter Co-authored-by: Tim Taylor Co-authored-by: KTrain <69028025+KTrain5169@users.noreply.github.com> Co-authored-by: Pooya Parsa Co-authored-by: Andrey Skladchikov <4318513+andrey-skl@users.noreply.github.com> Co-authored-by: skoch13 Co-authored-by: kzrnm Co-authored-by: coderaiser Co-authored-by: Jamie Magee Co-authored-by: Vaibhav Mittal Co-authored-by: Chris Burroughs Co-authored-by: ant-kurt Co-authored-by: bogini Co-authored-by: ant-kurt <209710463+ant-kurt@users.noreply.github.com> Co-authored-by: Carl Meyer Co-authored-by: Mathias Maisberger Co-authored-by: Mathias Maisberger Co-authored-by: Trim21 Co-authored-by: HRAshton <12210721+HRAshton@users.noreply.github.com> Co-authored-by: luo2430 <127001012+luo2430@users.noreply.github.com> Co-authored-by: Flo HUCK Co-authored-by: Vardo Ternos Co-authored-by: Bernát Gábor Co-authored-by: CherfaElyes <152391385+CherfaElyes@users.noreply.github.com> Co-authored-by: Velizar Kalapov <87693906+vkalapov@users.noreply.github.com> Co-authored-by: Thomas Rooney Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Aurélien Pupier Co-authored-by: Anca Antochi Co-authored-by: Aaron Feledy Co-authored-by: Aaron Feledy Co-authored-by: Zach Snell Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> Co-authored-by: Andres Almiray Co-authored-by: Dmitry Pavlov Co-authored-by: Michael Ferrari Co-authored-by: Mathieu Bélanger <56379077+mbelangergit@users.noreply.github.com> * bitrise.json and bitrise-step.json descriptions (#6) * descriptions for the Bitrise JSON schema * removing urls temporarily * yaml descriptions added * Added more descriptions to bitrise.json * minor fixes * bitrise-step.json descriptions * Update descriptions in bitrise.json after review Updated descriptions in bitrise.json after review * Update descriptions in bitrise-step.json after review Updated descriptions for various properties in the bitrise-step JSON schema after a review. * Update bitrise-step.json * Update bitrise-step.json * Remove unused step schema propoerties * format_version and triggers description update * Schema fixes * Add step based containerisation fields * Fix container schema * Improve steps' json schema and sync it with the bitrise.yaml json schema * Remove step based containerisation properties * Use the same step schema for both bitrise.json and bitrise-step.json * Remove new containerisation related schemas * Resolve duplicated step schema --------- Co-authored-by: Krisztián Gödrei * Run prettier --------- Signed-off-by: Jem Davies Signed-off-by: Vaibhav mittal Signed-off-by: Aurélien Pupier Co-authored-by: Hayssam Saleh Co-authored-by: Jem Davies <131159520+jem-davies@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jamie Tanna Co-authored-by: Ville Skyttä Co-authored-by: Pavel Bychko Co-authored-by: Shane Frasier Co-authored-by: Stefan VanBuren Co-authored-by: Micha Reiser Co-authored-by: Rene Nulsch <33263735+ReneNulschDE@users.noreply.github.com> Co-authored-by: sxwebdev Co-authored-by: leecow Co-authored-by: Ruben J. Jongejan Co-authored-by: Giancarlo Calderón Cárdenas Co-authored-by: Edwin Kofler Co-authored-by: Mitesh Ashar Co-authored-by: domdomegg Co-authored-by: Jordan GAZEAU Co-authored-by: Sayan Sisodiya Co-authored-by: Jan Klass Co-authored-by: Lars K.L. Co-authored-by: rosidae0 <82954131+rosidae@users.noreply.github.com> Co-authored-by: Jamie Tanna Co-authored-by: Çağlar ORHAN <401240+caglarorhan@users.noreply.github.com> Co-authored-by: Jose Sierra <165445418+Ktsierra@users.noreply.github.com> Co-authored-by: Tobbe Lundberg Co-authored-by: Rob Fox Co-authored-by: Claude Opus 4.5 Co-authored-by: Kang Hyojun Co-authored-by: Max Maximov Co-authored-by: Andrew Morrison Co-authored-by: github-actions[bot] Co-authored-by: yuto <43196286+yuto343@users.noreply.github.com> Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com> Co-authored-by: Sean McCollum Co-authored-by: Johannes Frey Co-authored-by: Jo <10510431+j178@users.noreply.github.com> Co-authored-by: Yoav Yanilov Co-authored-by: Charlie Marsh Co-authored-by: Yevhenii Tiutiunnyk Co-authored-by: btea <2356281422@qq.com> Co-authored-by: btea Co-authored-by: Маг Ильяс DOMA Co-authored-by: ctfer-io-bot <160312728+ctfer-io-bot@users.noreply.github.com> Co-authored-by: pandatix Co-authored-by: Jonathan COURTY <139225837+Johntycour@users.noreply.github.com> Co-authored-by: adam jones Co-authored-by: Eric Dallo Co-authored-by: Cristovao Cordeiro Co-authored-by: Joel Rosario Co-authored-by: vedubhat Co-authored-by: Yogesh Nikam <60032699+yogeshnikam671@users.noreply.github.com> Co-authored-by: Sufiyan Co-authored-by: Ketan Padegaonkar Co-authored-by: CEnnis91 Co-authored-by: Jonathan Otsuka <105506+djgoku@users.noreply.github.com> Co-authored-by: David Peter Co-authored-by: Tim Taylor Co-authored-by: KTrain <69028025+KTrain5169@users.noreply.github.com> Co-authored-by: Pooya Parsa Co-authored-by: Andrey Skladchikov <4318513+andrey-skl@users.noreply.github.com> Co-authored-by: skoch13 Co-authored-by: kzrnm Co-authored-by: coderaiser Co-authored-by: Jamie Magee Co-authored-by: Vaibhav Mittal Co-authored-by: Chris Burroughs Co-authored-by: ant-kurt Co-authored-by: bogini Co-authored-by: ant-kurt <209710463+ant-kurt@users.noreply.github.com> Co-authored-by: Carl Meyer Co-authored-by: Mathias Maisberger Co-authored-by: Mathias Maisberger Co-authored-by: Trim21 Co-authored-by: HRAshton <12210721+HRAshton@users.noreply.github.com> Co-authored-by: luo2430 <127001012+luo2430@users.noreply.github.com> Co-authored-by: Flo HUCK Co-authored-by: Vardo Ternos Co-authored-by: Bernát Gábor Co-authored-by: CherfaElyes <152391385+CherfaElyes@users.noreply.github.com> Co-authored-by: Velizar Kalapov <87693906+vkalapov@users.noreply.github.com> Co-authored-by: Thomas Rooney Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Aurélien Pupier Co-authored-by: Anca Antochi Co-authored-by: Aaron Feledy Co-authored-by: Aaron Feledy Co-authored-by: Zach Snell Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> Co-authored-by: Andres Almiray Co-authored-by: Dmitry Pavlov Co-authored-by: Michael Ferrari Co-authored-by: Mathieu Bélanger <56379077+mbelangergit@users.noreply.github.com> Co-authored-by: Zoltán Bába --- src/schema-validation.jsonc | 3 + src/schemas/json/bitrise-step.json | 163 +++++--- src/schemas/json/bitrise.json | 577 +++++++++++++---------------- 3 files changed, 367 insertions(+), 376 deletions(-) diff --git a/src/schema-validation.jsonc b/src/schema-validation.jsonc index 99db70bb68c..b908cc5a006 100644 --- a/src/schema-validation.jsonc +++ b/src/schema-validation.jsonc @@ -797,6 +797,9 @@ "azure-iot-edgehub-deployment-1.2.json": { "unknownKeywords": ["examples", "contentMediaType"] }, + "bitrise.json": { + "externalSchema": ["bitrise-step.json"] + }, "bower.json": { "externalSchema": ["base-04.json"] }, diff --git a/src/schemas/json/bitrise-step.json b/src/schemas/json/bitrise-step.json index 6eb95304735..b75f83ab454 100644 --- a/src/schemas/json/bitrise-step.json +++ b/src/schemas/json/bitrise-step.json @@ -1,14 +1,17 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://json.schemastore.org/bitrise-step.json", "$ref": "#/definitions/StepModel", "definitions": { "AptGetDepModel": { "properties": { "name": { - "type": "string" + "type": "string", + "description": "The name of the package to be installed via apt-get." }, "bin_name": { - "type": "string" + "type": "string", + "description": "The name of the binary. This is optional and can be used if the binary name differs from the package name." } }, "additionalProperties": false, @@ -17,7 +20,8 @@ "BashStepToolkitModel": { "properties": { "entry_file": { - "type": "string" + "type": "string", + "description": "The path to the bash script file that serves as the entry point for the Step." } }, "additionalProperties": false, @@ -26,10 +30,12 @@ "BrewDepModel": { "properties": { "name": { - "type": "string" + "type": "string", + "description": "The name of the package to be installed via Homebrew." }, "bin_name": { - "type": "string" + "type": "string", + "description": "The name of the binary. This is optional and can be used if the binary name differs from the package name." } }, "additionalProperties": false, @@ -38,7 +44,8 @@ "CheckOnlyDepModel": { "properties": { "name": { - "type": "string" + "type": "string", + "description": "The name of the binary or tool to check for. If it is not present on the system, the Step will fail before running." } }, "additionalProperties": false, @@ -47,10 +54,12 @@ "DependencyModel": { "properties": { "manager": { - "type": "string" + "type": "string", + "description": "The package manager used to handle the dependency." }, "name": { - "type": "string" + "type": "string", + "description": "The name of the dependency." } }, "additionalProperties": false, @@ -60,21 +69,27 @@ "properties": { "brew": { "items": { - "$ref": "#/definitions/BrewDepModel" + "$ref": "#/definitions/BrewDepModel", + "description": "A Homebrew dependency required by the Step." }, - "type": "array" + "type": "array", + "description": "List of Homebrew dependencies required by the Step." }, "apt_get": { "items": { - "$ref": "#/definitions/AptGetDepModel" + "$ref": "#/definitions/AptGetDepModel", + "description": "An apt-get dependency required by the Step." }, - "type": "array" + "type": "array", + "description": "List of apt-get dependencies required by the Step." }, "check_only": { "items": { - "$ref": "#/definitions/CheckOnlyDepModel" + "$ref": "#/definitions/CheckOnlyDepModel", + "description": "A dependency that is only checked for existence." }, - "type": "array" + "type": "array", + "description": "List of dependencies that are only checked for existence." } }, "additionalProperties": false, @@ -83,19 +98,23 @@ "ExecutableModel": { "properties": { "storage_uri": { - "type": "string" + "type": "string", + "description": "The URI where the executable binary is stored." }, "hash": { - "type": "string" + "type": "string", + "description": "The hash of the executable binary for integrity verification." } }, - "type": "object" + "type": "object", + "description": "Platform-specific executable binary." }, "GoStepToolkitModel": { "required": ["package_name"], "properties": { "package_name": { - "type": "string" + "type": "string", + "description": "The name of the Go package that serves as the entry point for the Step." } }, "additionalProperties": false, @@ -104,82 +123,110 @@ "StepModel": { "properties": { "title": { - "type": "string" + "type": "string", + "description": "The human-readable title of the Step." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of what the Step does." }, "description": { - "type": "string" + "type": "string", + "description": "A more detailed overview of the Step's function and configuration." }, "website": { - "type": "string" + "type": "string", + "description": "A web URL where users can find more information about the Step or the tools and services it implements." }, "source_code_url": { - "type": "string" + "type": "string", + "description": "The URL of the repository of the Step's source code." }, "support_url": { - "type": "string" + "type": "string", + "description": "A URL where users can get support for the Step." }, "published_at": { "type": "string", - "format": "date-time" + "format": "date-time", + "description": "The date and time when the Step was published to the Step Library. This is auto-generated and should not be set manually." }, "source": { - "$ref": "#/definitions/StepSourceModel" + "$ref": "#/definitions/StepSourceModel", + "description": "The source code repository and commit information of the Step." }, "asset_urls": { "patternProperties": { ".*": { - "type": "string" + "type": "string", + "description": "A URL pointing to a Step asset such as an icon image." } }, - "type": "object" + "type": "object", + "description": "URLs of assets associated with the Step, such as icon images. This is auto-generated and only set in the spec.json file in the Step Library." }, "host_os_tags": { "items": { - "type": "string" + "type": "string", + "description": "The host operating system tag." }, - "type": "array" + "type": "array", + "description": "This property defines the host operating systems the Step is compatible with. For example, `linux` or `macos`." }, "project_type_tags": { "items": { - "type": "string" + "type": "string", + "description": "The project type tag." }, - "type": "array" + "type": "array", + "description": "This property defines the project type category of the Step. For example, `flutter` or `ios`." }, "type_tags": { "items": { - "type": "string" + "type": "string", + "description": "A functional category tag. For example, `utility`, `test`, or `notification`." }, - "type": "array" + "type": "array", + "description": "This property defines the functional category of the Step. For example, `utility`, `test`, or `notification`." }, "dependencies": { "items": { "$ref": "#/definitions/DependencyModel" }, - "type": "array" + "type": "array", + "description": "The dependencies required by the Step." }, "toolkit": { - "$ref": "#/definitions/StepToolkitModel" + "$ref": "#/definitions/StepToolkitModel", + "description": "The toolkit used by the Step." }, "deps": { - "$ref": "#/definitions/DepsModel" + "$ref": "#/definitions/DepsModel", + "description": "The dependencies required by the Step." }, "is_requires_admin_user": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the Step requires admin user privileges to run." }, "is_always_run": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the Step will always run, even if a previous Step in the Workflow failed." }, "is_skippable": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the build won't fail even if this Step fails. For example, if a Step restoring a cache archive fails, you might still want to run the build." }, "run_if": { - "type": "string" + "type": "string", + "description": "This property sets conditions for running a Step. It requires boolean value or a valid Go template expression." }, "timeout": { - "type": "integer" + "type": "integer", + "description": "This property defines a time limit for a Step: if the Step runs longer than the defined time, the Step fails. Define the limit in seconds." + }, + "no_output_timeout": { + "type": "integer", + "description": "This property defines a time limit for a Step that produces no output: if the Step runs for the defined number of seconds without producing any output, the Step fails. Define the limit in seconds." }, "meta": { "patternProperties": { @@ -187,7 +234,8 @@ "additionalProperties": true } }, - "type": "object" + "type": "object", + "description": "Additional metadata related to the Step." }, "inputs": { "items": { @@ -196,9 +244,11 @@ "additionalProperties": true } }, - "type": "object" + "type": "object", + "description": "An input parameter of the Step." }, - "type": "array" + "type": "array", + "description": "The inputs of the Step." }, "outputs": { "items": { @@ -207,9 +257,11 @@ "additionalProperties": true } }, - "type": "object" + "type": "object", + "description": "An output parameter of the Step." }, - "type": "array" + "type": "array", + "description": "The outputs the Step generates." }, "executables": { "description": "Platform-specific executable binaries", @@ -225,10 +277,12 @@ "StepSourceModel": { "properties": { "git": { - "type": "string" + "type": "string", + "description": "The Git repository URL of the Step's source code." }, "commit": { - "type": "string" + "type": "string", + "description": "The commit hash for the version tag of the Step's current version." } }, "additionalProperties": false, @@ -237,15 +291,16 @@ "StepToolkitModel": { "properties": { "bash": { - "$ref": "#/definitions/BashStepToolkitModel" + "$ref": "#/definitions/BashStepToolkitModel", + "description": "The Bash toolkit configuration for the Step." }, "go": { - "$ref": "#/definitions/GoStepToolkitModel" + "$ref": "#/definitions/GoStepToolkitModel", + "description": "The Go toolkit configuration for the Step." } }, "additionalProperties": false, "type": "object" } - }, - "id": "https://json.schemastore.org/bitrise-step.json" + } } diff --git a/src/schemas/json/bitrise.json b/src/schemas/json/bitrise.json index 1faaaa9e504..ba6123e5e52 100644 --- a/src/schemas/json/bitrise.json +++ b/src/schemas/json/bitrise.json @@ -6,40 +6,24 @@ "AppModel": { "properties": { "title": { - "type": "string" + "type": "string", + "description": "The title of the project." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of the project." }, "description": { - "type": "string" + "type": "string", + "description": "A detailed description of the project." }, "status_report_name": { - "$ref": "#/definitions/StatusReportNameModel" + "$ref": "#/definitions/StatusReportNameModel", + "description": "The name that will appear on the status report sent to connected services (like GitHub, GitLab, Bitbucket, and so on) after the build is finished." }, "envs": { - "$ref": "#/definitions/EnvModel" - } - }, - "additionalProperties": false, - "type": "object" - }, - "AptGetDepModel": { - "properties": { - "name": { - "type": "string" - }, - "bin_name": { - "type": "string" - } - }, - "additionalProperties": false, - "type": "object" - }, - "BashStepToolkitModel": { - "properties": { - "entry_file": { - "type": "string" + "$ref": "#/definitions/EnvModel", + "description": "Environment Variables defined for the project." } }, "additionalProperties": false, @@ -52,22 +36,28 @@ ], "properties": { "format_version": { - "type": "string" + "type": "string", + "description": "The version of the Bitrise configuration format. The Bitrise CLI checks it to ensure compatibility between the configuration file and the CLI version. This is relevant for locally run builds: on the Bitrise website, the CLI is always up to date, so the `format_version` property doesn't have an effect on builds triggered." }, "default_step_lib_source": { - "type": "string" + "type": "string", + "description": "The default Step library for the Steps used in your configuration. Bitrise uses this source if no specific source is provided for a given Step." }, "project_type": { - "type": "string" + "type": "string", + "description": "The type of your Bitrise project, such as ios, android, flutter, and so on." }, "title": { - "type": "string" + "type": "string", + "description": "The title of the Bitrise configuration." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of the Bitrise configuration." }, "description": { - "type": "string" + "type": "string", + "description": "A detailed description of the Bitrise configuration." }, "services": { "patternProperties": { @@ -75,7 +65,8 @@ "$ref": "#/definitions/ContainerModel" } }, - "type": "object" + "type": "object", + "description": "Docker container definitions used by Steps as service containers." }, "containers": { "patternProperties": { @@ -83,7 +74,8 @@ "$ref": "#/definitions/ContainerModel" } }, - "type": "object" + "type": "object", + "description": "Docker container definitions used by Steps as execution containers." }, "app": { "$ref": "#/definitions/AppModel" @@ -94,13 +86,15 @@ "additionalProperties": true } }, - "type": "object" + "type": "object", + "description": "Stores project metadata key-value pairs related to the Bitrise configuration. Most importantly, it defines the default stack and the build machine type for the project." }, "trigger_map": { "items": { "$ref": "#/definitions/TriggerMapItemModel" }, - "type": "array" + "type": "array", + "description": "Defines the build triggers on a project level. This is the legacy method of configuring triggers: we recommend using target-based triggers defined as part of a Pipeline or a Workflow instead." }, "pipelines": { "patternProperties": { @@ -108,7 +102,8 @@ "$ref": "#/definitions/PipelineModel" } }, - "type": "object" + "type": "object", + "description": "Define Pipelines in your project's configuration. Pipelines can be used to organize the entire CI/CD process and to set up advanced configurations with multiple different tasks running parallel and/or sequentially." }, "stages": { "patternProperties": { @@ -116,7 +111,8 @@ "$ref": "#/definitions/StageModel" } }, - "type": "object" + "type": "object", + "description": "Defines Stages in your configuration. A Stage is a collection of Workflows that are executed sequentially as part of a Pipeline." }, "workflows": { "patternProperties": { @@ -124,7 +120,8 @@ "$ref": "#/definitions/WorkflowModel" } }, - "type": "object" + "type": "object", + "description": "The Workflows included in your configuration. A Workflow is a collection of Steps: reusable, configurable units of work. Steps are executed sequentially within a Workflow." }, "step_bundles": { "patternProperties": { @@ -132,40 +129,23 @@ "$ref": "#/definitions/StepBundleModel" } }, - "type": "object" + "type": "object", + "description": "Step bundles allow you to group multiple Steps into a single unit. With Step bundles, you can reuse Steps and sequences of Steps." }, "tools": { - "$ref": "#/definitions/ToolsModel" + "$ref": "#/definitions/ToolsModel", + "description": "Declarative configuration for tool versions used in the build. " }, "tool_config": { "$ref": "#/definitions/ToolConfigModel" }, "include": { "items": { - "$ref": "#/definitions/IncludeItemModel" + "$ref": "#/definitions/IncludeItemModel", + "description": "An included configuration file." }, - "type": "array" - } - }, - "additionalProperties": false, - "type": "object" - }, - "BrewDepModel": { - "properties": { - "name": { - "type": "string" - }, - "bin_name": { - "type": "string" - } - }, - "additionalProperties": false, - "type": "object" - }, - "CheckOnlyDepModel": { - "properties": { - "name": { - "type": "string" + "type": "array", + "description": "The `include` property allows you to use other configuration YAML files in your Bitrise configuration, to break down large, complex YAML files into smaller, modular components." } }, "additionalProperties": false, @@ -175,46 +155,28 @@ "required": ["image"], "properties": { "image": { - "type": "string" + "type": "string", + "description": "The Docker image for the container, in `[REPOSITORY[:TAG]]` format." }, "credentials": { - "$ref": "#/definitions/DockerCredentialModel" + "$ref": "#/definitions/DockerCredentialModel", + "description": "Credentials for authenticating with a Docker registry when pulling the image." }, "ports": { "type": "array", + "description": "Port mappings that expose container ports to the host or to other containers.", "items": { - "type": "string" + "type": "string", + "description": "A port mapping in the format `[HostPort]:[ContainerPort]`." } }, "envs": { - "$ref": "#/definitions/EnvModel" + "$ref": "#/definitions/EnvModel", + "description": "Environment variables passed to the Docker container. Workflow-level `envs` are also inherited by containers." }, "options": { - "type": "string" - } - }, - "additionalProperties": false, - "type": "object" - }, - "DepsModel": { - "properties": { - "brew": { - "items": { - "$ref": "#/definitions/BrewDepModel" - }, - "type": "array" - }, - "apt_get": { - "items": { - "$ref": "#/definitions/AptGetDepModel" - }, - "type": "array" - }, - "check_only": { - "items": { - "$ref": "#/definitions/CheckOnlyDepModel" - }, - "type": "array" + "type": "string", + "description": "Additional options passed to the `docker create` command. Note: `--network`, `--volume` (`-v`), and `--entrypoint` are not supported." } }, "additionalProperties": false, @@ -224,13 +186,16 @@ "required": ["username", "password"], "properties": { "username": { - "type": "string" + "type": "string", + "description": "The username used for the `docker login` command." }, "password": { - "type": "string" + "type": "string", + "description": "The password used for the `docker login` command. Use a Secret environment variable to avoid exposing the value in the configuration." }, "server": { - "type": "string" + "type": "string", + "description": "The server used for the `docker login` command. Optional if the server is already part of the image reference." } }, "additionalProperties": false, @@ -243,36 +208,33 @@ "additionalProperties": true } }, - "type": "object" + "type": "object", + "description": "An Environment Variable defined as a key-value pair, with optional properties." }, - "type": "array" - }, - "GoStepToolkitModel": { - "required": ["package_name"], - "properties": { - "package_name": { - "type": "string" - } - }, - "additionalProperties": false, - "type": "object" + "type": "array", + "description": "A list of Environment Variables." }, "PipelineModel": { "properties": { "title": { - "type": "string" + "type": "string", + "description": "The title of the Pipeline." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of the Pipeline." }, "description": { - "type": "string" + "type": "string", + "description": "A detailed description of the Pipeline." }, "triggers": { - "$ref": "#/definitions/TriggersModel" + "$ref": "#/definitions/TriggersModel", + "description": "Target-based triggers defined for the Pipeline: if a code event matches the condition defined in a trigger, Bitrise will trigger a build with the Pipeline." }, "status_report_name": { - "$ref": "#/definitions/StatusReportNameModel" + "$ref": "#/definitions/StatusReportNameModel", + "description": "The name that will appear on the status report sent to connected services (like GitHub, GitLab, Bitbucket, and so on) after the build is finished." }, "stages": { "items": { @@ -281,9 +243,11 @@ "$ref": "#/definitions/StageModel" } }, - "type": "object" + "type": "object", + "description": "A Stage that is part of the Pipeline configuration." }, - "type": "array" + "type": "array", + "description": "The list of Stages that are part of the Pipeline configuration." }, "workflows": { "patternProperties": { @@ -291,7 +255,8 @@ "$ref": "#/definitions/GraphPipelineWorkflowModel" } }, - "type": "object" + "type": "object", + "description": "The Workflows that are part of the Pipeline configuration. You can create dependencies between Workflows with the `depends_on` property." }, "priority": { "$ref": "#/definitions/PriorityModel" @@ -304,22 +269,27 @@ "properties": { "depends_on": { "items": { - "type": "string" + "type": "string", + "description": "The name of a Workflow that this Workflow depends on." }, - "type": "array" + "type": "array", + "description": "This property defines the Workflows that this Workflow depends on. If any of the Workflows in the list fails, this Workflow won't run." }, "abort_on_fail": { - "type": "boolean" + "type": "boolean", + "description": "When this property is `true`, the Pipeline and any other running Workflows are aborted if this Workflow fails." }, "should_always_run": { "type": "string", - "enum": ["off", "workflow"] + "enum": ["none", "workflow"], + "description": "This property defines whether a Workflow should run if a previous Workflow failed. Set to `workflow` if you want this Workflow to always run regardless of failures. The default value is `none`." }, "run_if": { "$ref": "#/definitions/GraphPipelineWorkflowRunIfModel" }, "parallel": { - "oneOf": [{ "type": "integer" }, { "type": "string" }] + "oneOf": [{ "type": "integer" }, { "type": "string" }], + "description": "The `parallel` property allows you to run copies of the same Workflow in parallel, in a single instruction. This is particularly useful for test sharding. It takes an integer or an Environment Variable." }, "uses": { "type": "string" @@ -335,28 +305,35 @@ "required": ["expression"], "properties": { "expression": { - "type": "string" + "type": "string", + "description": "A Go template expression that defines the conditions for running the Workflow." } }, "additionalProperties": false, - "type": "object" + "type": "object", + "description": "The conditions defined for running a Workflow." }, "StageModel": { "properties": { "title": { - "type": "string" + "type": "string", + "description": "The title of the Stage." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of the Stage." }, "description": { - "type": "string" + "type": "string", + "description": "A detailed description of the Stage." }, "abort_on_fail": { - "type": "boolean" + "type": "boolean", + "description": "When this property is true, the Pipeline and any other running Stages are aborted if this Stage fails." }, "should_always_run": { - "type": "boolean" + "type": "boolean", + "description": "When this property is true, the Stage will always run, even if a previous Stage in the Pipeline failed." }, "workflows": { "items": { @@ -365,9 +342,11 @@ "$ref": "#/definitions/WorkflowStageConfigModel" } }, - "type": "object" + "type": "object", + "description": "A Workflow that is part of the Stage configuration." }, - "type": "array" + "type": "array", + "description": "The list of Workflows that are part of the Stage configuration." } }, "additionalProperties": false, @@ -375,111 +354,17 @@ }, "StatusReportNameModel": { "type": "string", + "description": "The name that will appear on the status report sent to connected services (like GitHub, GitLab, Bitbucket, etc.) after the build is finished.", "minLength": 1, "maxLength": 100, "pattern": "^[a-zA-Z0-9,./():\\-_ <>\\[\\]\\|]*$" }, - "StepModel": { - "properties": { - "title": { - "type": "string" - }, - "summary": { - "type": "string" - }, - "description": { - "type": "string" - }, - "website": { - "type": "string" - }, - "source_code_url": { - "type": "string" - }, - "support_url": { - "type": "string" - }, - "published_at": { - "type": "string", - "format": "date-time" - }, - "source": { - "$ref": "#/definitions/StepSourceModel" - }, - "asset_urls": { - "patternProperties": { - ".*": { - "type": "string" - } - }, - "type": "object" - }, - "host_os_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "project_type_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "type_tags": { - "items": { - "type": "string" - }, - "type": "array" - }, - "toolkit": { - "$ref": "#/definitions/StepToolkitModel" - }, - "deps": { - "$ref": "#/definitions/DepsModel" - }, - "is_requires_admin_user": { - "type": "boolean" - }, - "is_always_run": { - "type": "boolean" - }, - "is_skippable": { - "type": "boolean" - }, - "run_if": { - "type": "string" - }, - "timeout": { - "type": "integer" - }, - "no_output_timeout": { - "type": "integer" - }, - "meta": { - "patternProperties": { - ".*": { - "additionalProperties": true - } - }, - "type": "object" - }, - "inputs": { - "$ref": "#/definitions/EnvModel" - }, - "outputs": { - "$ref": "#/definitions/EnvModel" - } - }, - "additionalProperties": false, - "type": "object" - }, "ToolsModel": { "description": "Mapping of tool IDs to versions to set up. Version syntax supports exact versions (e.g. '1.2.3'), partial matches to the latest release (e.g. '22:latest'), partial matches to installed versions (e.g. '1.2:installed'), as well as the special aliases 'latest' and 'installed' to select the highest respective version.", "patternProperties": { ".*": { "type": "string", - "description": "Tool version to set up. Version syntax supports exact versions (e.g. '1.2.3'), partial matches to the latest release (e.g. '22:latest'), partial matches to installed versions (e.g. '1.2:installed'), as well as the special aliases 'latest' and 'installed' to select the highest respective version." + "description": "The version of the tool to set up." } }, "type": "object" @@ -508,25 +393,31 @@ "TriggersModel": { "properties": { "enabled": { - "type": "boolean" + "type": "boolean", + "description": "The property determines whether a defined trigger is active. The default value is `true`. If you want to disable the trigger, set it to `false`." }, "push": { "items": { - "$ref": "#/definitions/PushTriggerModel" + "$ref": "#/definitions/PushTriggerModel", + "description": "A push trigger configuration." }, - "type": "array" + "type": "array", + "description": "Code push triggers: they define the conditions for triggering a Bitrise build when code is pushed to the project's repository." }, "pull_request": { "items": { - "$ref": "#/definitions/PullrequestTriggerModel" + "$ref": "#/definitions/PullrequestTriggerModel", + "description": "A pull request trigger configuration." }, - "type": "array" + "type": "array", + "description": "Pull request triggers: they define the conditions for triggering a Bitrise build when a pull request is opened in the project's repository." }, "tag": { "items": { "$ref": "#/definitions/TagTriggerModel" }, - "type": "array" + "type": "array", + "description": "Git tag triggers: they define the conditions for triggering a Bitrise build when a Git tag is pushed to the project's repository." } }, "additionalProperties": false, @@ -538,10 +429,12 @@ "required": ["pattern"], "properties": { "pattern": { - "type": "string" + "type": "string", + "description": "A glob pattern used to match against the condition." }, "last_commit": { - "type": "boolean" + "type": "boolean", + "description": "Defines whether Bitrise should evaluate every commit message or changed file in a code push or only those belonging to the most recent commit. Its default value is `false`." } } }, @@ -549,10 +442,12 @@ "required": ["regex"], "properties": { "regex": { - "type": "string" + "type": "string", + "description": "A regular expression pattern used to match against the condition." }, "last_commit": { - "type": "boolean" + "type": "boolean", + "description": "Defines whether Bitrise should evaluate every commit message or changed file in a code push or only those belonging to the most recent commit. Its default value is `false`." } } } @@ -563,7 +458,8 @@ "PushTriggerModel": { "properties": { "enabled": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the push trigger is active and can trigger Bitrise builds." }, "priority": { "$ref": "#/definitions/PriorityModel" @@ -572,19 +468,22 @@ "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "A branch of the project's repository. Bitrise triggers a build if code is pushed to the branch defined in this property." }, "commit_message": { "oneOf": [ { "$ref": "#/definitions/PushTriggerMapItemModelCommitsCondition" }, { "type": "string" } - ] + ], + "description": "Define a Git commit message that should trigger a Bitrise build." }, "changed_files": { "oneOf": [ { "$ref": "#/definitions/PushTriggerMapItemModelCommitsCondition" }, { "type": "string" } - ] + ], + "description": "Set a filepath or a folder. If any file or files change in that location, Bitrise triggers a build." } }, "additionalProperties": false, @@ -593,49 +492,58 @@ "PullrequestTriggerModel": { "properties": { "enabled": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the pull request trigger is active and can trigger Bitrise builds." }, "priority": { - "$ref": "#/definitions/PriorityModel" + "$ref": "#/definitions/PriorityModel", + "description": "The priority of the pull request trigger." }, "draft_enabled": { - "type": "boolean" + "type": "boolean", + "description": "If this property is `true`, draft pull requests can trigger builds, too." }, "source_branch": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Bitrise triggers a build if the branch name in this property matches the source branch of a pull request opened in the project's repository." }, "target_branch": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Bitrise triggers a build if the branch name in the property matches the target branch of a pull request opened in the project's repository." }, "label": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "If a pull request's label matches the label in this property, Bitrise triggers a build." }, "comment": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "This property looks for comments on pull requests to trigger Bitrise builds." }, "commit_message": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Define a Git commit message that should trigger a Bitrise build." }, "changed_files": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Set a filepath or a folder. If any file or files change in that location in a pull request, Bitrise triggers a build." } }, "additionalProperties": false, @@ -644,40 +552,19 @@ "TagTriggerModel": { "properties": { "enabled": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the tag trigger is active and can trigger Bitrise builds." }, "priority": { - "$ref": "#/definitions/PriorityModel" + "$ref": "#/definitions/PriorityModel", + "description": "The priority of the tag trigger." }, "name": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] - } - }, - "additionalProperties": false, - "type": "object" - }, - "StepSourceModel": { - "properties": { - "git": { - "type": "string" - }, - "commit": { - "type": "string" - } - }, - "additionalProperties": false, - "type": "object" - }, - "StepToolkitModel": { - "properties": { - "bash": { - "$ref": "#/definitions/BashStepToolkitModel" - }, - "go": { - "$ref": "#/definitions/GoStepToolkitModel" + ], + "description": "This property looks for the name of a Git tag to trigger a Bitrise build." } }, "additionalProperties": false, @@ -686,7 +573,8 @@ "TriggerMapItemModelRegexCondition": { "properties": { "regex": { - "type": "string" + "type": "string", + "description": "A regular expression pattern used to match against specific code event attributes." } }, "additionalProperties": false, @@ -696,77 +584,92 @@ "properties": { "type": { "type": "string", - "enum": ["push", "pull_request", "tag"] + "enum": ["push", "pull_request", "tag"], + "description": "The type of the code event the trigger looks for." }, "enabled": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, the trigger is active and can trigger Bitrise builds." }, "pipeline": { - "type": "string" + "type": "string", + "description": "The name of the Pipeline that will be triggered if the code event matches the trigger condition." }, "workflow": { - "type": "string" + "type": "string", + "description": "The name of the Workflow that will be triggered if the code event matches the trigger condition." }, "push_branch": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "A branch of the project's repository. Bitrise triggers a build if code is pushed to the branch defined in this property." }, "commit_message": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Define a Git commit message that should trigger a Bitrise build." }, "changed_files": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Set a filepath or a folder. If any file or files change in that location, Bitrise triggers a build." }, "pull_request_source_branch": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Bitrise triggers a build if the branch name in this property matches the source branch of a pull request opened in the project's repository." }, "pull_request_target_branch": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Bitrise triggers a build if the branch name in the property matches the target branch of a pull request opened in the project's repository." }, "draft_pull_request_enabled": { - "type": "boolean" + "type": "boolean", + "description": "If this property is `true`, draft pull requests can trigger builds, too." }, "pull_request_label": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "You can mark pull requests with labels. If a pull request's label matches the label in this property, Bitrise triggers a build." }, "pull_request_comment": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "This property looks for comments on pull requests to trigger Bitrise builds." }, "tag": { "oneOf": [ { "$ref": "#/definitions/TriggerMapItemModelRegexCondition" }, { "type": "string" } - ] + ], + "description": "Bitrise triggers a build when a Git tag matching the tag defined in this property is pushed to the project's repository." }, "pattern": { - "type": "string" + "type": "string", + "description": "A pattern used to match against specific code event attributes." }, "is_pull_request_allowed": { - "type": "boolean" + "type": "boolean", + "description": "If this property is true, pull requests are allowed to trigger Bitrise builds." } }, "additionalProperties": false, @@ -776,10 +679,12 @@ "required": ["steps"], "properties": { "container": { - "type": "string" + "type": "string", + "description": "The name of the container that will be used as the execution environment." }, "services": { "type": "array", + "description": "The name of the service container that will be used to run services.", "items": { "type": "string" } @@ -788,13 +693,15 @@ "items": { "patternProperties": { "^(?!bundle::)(?!with$).*": { - "$ref": "#/definitions/StepModel" + "$ref": "https://json.schemastore.org/bitrise-step.json", + "description": "A Step in the Workflow." } }, "additionalProperties": false, "type": "object" }, - "type": "array" + "type": "array", + "description": "The list of Steps to be executed within the specified container environment." } }, "additionalProperties": false, @@ -803,7 +710,8 @@ "WorkflowStageConfigModel": { "properties": { "run_if": { - "type": "string" + "type": "string", + "description": "A Go template expression that defines the conditions for running the Workflow within the Stage." } }, "additionalProperties": false, @@ -812,34 +720,43 @@ "WorkflowModel": { "properties": { "title": { - "type": "string" + "type": "string", + "description": "The title of the Workflow." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of the Workflow." }, "description": { - "type": "string" + "type": "string", + "description": "A detailed description of the Workflow." }, "triggers": { - "$ref": "#/definitions/TriggersModel" + "$ref": "#/definitions/TriggersModel", + "description": "Target-based triggers defined for the Workflow: if a code event matches the condition defined in a trigger, Bitrise will trigger a build with the Workflow." }, "status_report_name": { "$ref": "#/definitions/StatusReportNameModel" }, "before_run": { "items": { - "type": "string" + "type": "string", + "description": "The name of a Workflow that will run before this Workflow starts." }, - "type": "array" + "type": "array", + "description": "The Workflows that will run before this Workflow starts." }, "after_run": { "items": { - "type": "string" + "type": "string", + "description": "The name of a Workflow that will run after this Workflow is successfully finished." }, - "type": "array" + "type": "array", + "description": "The Workflows that will run after this Workflow is successfully finished." }, "envs": { - "$ref": "#/definitions/EnvModel" + "$ref": "#/definitions/EnvModel", + "description": "Environment Variables defined for the Workflow." }, "steps": { "items": { @@ -848,22 +765,26 @@ "$ref": "#/definitions/StepBundleOverrideModel" }, "^with$": { - "$ref": "#/definitions/WithModel" + "$ref": "#/definitions/WithModel", + "description": "A with group defining Steps to be executed within a specific container environment." }, "^(?!bundle::)(?!with$).*": { - "$ref": "#/definitions/StepModel" + "$ref": "https://json.schemastore.org/bitrise-step.json" } }, "additionalProperties": false, "type": "object" }, - "type": "array" + "type": "array", + "description": "The list of Steps in the Workflow." }, "priority": { - "$ref": "#/definitions/PriorityModel" + "$ref": "#/definitions/PriorityModel", + "description": "The priority of the Workflow." }, "tools": { - "$ref": "#/definitions/ToolsModel" + "$ref": "#/definitions/ToolsModel", + "description": "Declarative configuration for tool versions used in the Workflow." }, "meta": { "patternProperties": { @@ -871,7 +792,8 @@ "additionalProperties": true } }, - "type": "object" + "type": "object", + "description": "Stores project metadata key-value pairs. Most importantly, it defines the stack and the machine type for the Workflow." } }, "additionalProperties": false, @@ -880,19 +802,23 @@ "StepBundleModel": { "properties": { "title": { - "type": "string" + "type": "string", + "description": "The title of the Step bundle." }, "summary": { - "type": "string" + "type": "string", + "description": "A short summary of the Step bundle." }, "description": { - "type": "string" + "type": "string", + "description": "A detailed description of the Step bundle." }, "envs": { "$ref": "#/definitions/EnvModel" }, "inputs": { - "$ref": "#/definitions/EnvModel" + "$ref": "#/definitions/EnvModel", + "description": "Inputs defined for the Step bundle: these are values that can be set when the Step bundle is added to a Workflow." }, "steps": { "items": { @@ -901,13 +827,14 @@ "$ref": "#/definitions/StepBundleOverrideModel" }, "^(?!bundle::)(?!with$).*": { - "$ref": "#/definitions/StepModel" + "$ref": "https://json.schemastore.org/bitrise-step.json" } }, "additionalProperties": false, "type": "object" }, - "type": "array" + "type": "array", + "description": "The Steps included in the Step bundle." } }, "additionalProperties": false, @@ -939,25 +866,31 @@ "properties": { "path": { "type": "string", - "minLength": 1 + "minLength": 1, + "description": "The file path of the included configuration file. This path is relative to the root of the repository." }, "repository": { - "type": "string" + "type": "string", + "description": "The name of the repository that contains the included configuration file. You do not need the URL, just the name. Leave it empty if the file is in the same repository as your current configuration file." }, "branch": { - "type": "string" + "type": "string", + "description": "The repository branch that contains the included configuration file. It has a lower priority than `tag` and `commit`." }, "commit": { - "type": "string" + "type": "string", + "description": "The commit hash of the commit that contains the included configuration file. It takes priority over `branch` and `tag` if they are all specified." }, "tag": { - "type": "string" + "type": "string", + "description": "The Git tag of the commit that contains the included configuration file. It has a higher priority than `branch` but a lower priority than `commit`." } }, "additionalProperties": false, "type": "object" }, "PriorityModel": { + "description": "Build priority determines a build's position in the build queue. A build with a higher priority is executed sooner than a build with a lower priority. You can set priorities for Pipelines, Workflows, build triggers, and when manually starting a new build.", "type": "integer", "maximum": 100, "minimum": -100