@pacp/spec 3.1.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -89,6 +89,8 @@ const product: Product = {
89
89
  sku: 'MES-001',
90
90
  manufacturer: 'Moveis Artisan',
91
91
  brand: 'Artisan Home',
92
+ category: [['Móveis', 'Mesas']],
93
+ collections: ['linha_artisan', 'lancamento_2026'],
92
94
  base_price: 2500,
93
95
  weight: { value: 45, unit: 'kg' },
94
96
  dimensions: { width: 160, height: 78, depth: 90, unit: 'cm' },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/validate.ts"],"sourcesContent":["export { schema, profiles, profileIds } from \"./schema.js\";\r\nexport { validate } from \"./validate.js\";\r\nexport type {\r\n ScalarValue,\r\n ImageType,\r\n Image,\r\n Measure,\r\n PhysicalDimensions,\r\n AttributeRef,\r\n AttributeValue,\r\n Option,\r\n LotPolicy,\r\n SalesUnit,\r\n Product,\r\n Predicate,\r\n Condition,\r\n Component,\r\n RuleOperation,\r\n Rule,\r\n Ruleset,\r\n LookupAxis,\r\n TableRow,\r\n Table,\r\n Dependency,\r\n Constraint,\r\n PriceList,\r\n Catalog,\r\n ProductRef,\r\n Context,\r\n Pricing,\r\n CatalogDocument,\r\n ProductDocument,\r\n PacpDocument,\r\n ProfileId,\r\n ValidationIssue,\r\n ValidationResult,\r\n} from \"./types.js\";\r\n","import { readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nfunction loadJson(relativePath: string): Record<string, unknown> {\r\n const fullPath = join(__dirname, relativePath);\r\n return JSON.parse(readFileSync(fullPath, \"utf8\"));\r\n}\r\n\r\nexport const schema = loadJson(\"./pacp.schema.json\") as Record<string, unknown>;\r\n\r\nexport const profiles = {\r\n moveis: loadJson(\"./profiles/moveis.schema.json\") as Record<string, unknown>,\r\n iluminacao: loadJson(\"./profiles/iluminacao.schema.json\") as Record<string, unknown>,\r\n \"pisos-revestimentos\": loadJson(\"./profiles/pisos-revestimentos.schema.json\") as Record<string, unknown>,\r\n \"fiscal-br\": loadJson(\"./profiles/fiscal-br.schema.json\") as Record<string, unknown>,\r\n} as const;\r\n\r\nexport type ProfileId = keyof typeof profiles;\r\n\r\nexport const profileIds = Object.keys(profiles) as ProfileId[];\r\n","import type { ValidationResult, ValidationIssue, PacpDocument } from \"./types.js\";\r\nimport { schema, profiles, type ProfileId } from \"./schema.js\";\r\n\r\nexport function validate(document: unknown): ValidationResult {\r\n let Ajv2020: typeof import(\"ajv/dist/2020\").default;\r\n let addFormats: typeof import(\"ajv-formats\").default;\r\n\r\n try {\r\n Ajv2020 = require(\"ajv/dist/2020\") as typeof import(\"ajv/dist/2020\").default;\r\n addFormats = require(\"ajv-formats\") as typeof import(\"ajv-formats\").default;\r\n } catch {\r\n throw new Error(\r\n 'Para usar validate(), instale ajv e ajv-formats: npm install ajv ajv-formats'\r\n );\r\n }\r\n\r\n const ajv = new Ajv2020({ allErrors: true, strict: false });\r\n addFormats(ajv);\r\n\r\n const issues: ValidationIssue[] = [];\r\n\r\n const validateSchema = ajv.compile(schema);\r\n const valid = validateSchema(document);\r\n\r\n if (!valid && validateSchema.errors) {\r\n for (const error of validateSchema.errors) {\r\n issues.push({\r\n code: \"SCHEMA\",\r\n path: error.instancePath || \"/\",\r\n message: error.message ?? \"Erro de validacao de schema\",\r\n });\r\n }\r\n }\r\n\r\n if (document && typeof document === \"object\" && !Array.isArray(document)) {\r\n const doc = document as Record<string, unknown>;\r\n const declaredProfiles = Array.isArray(doc.profiles) ? doc.profiles : [];\r\n\r\n for (const profileId of declaredProfiles) {\r\n if (typeof profileId !== \"string\") continue;\r\n\r\n const profileSchema = profiles[profileId as ProfileId];\r\n if (!profileSchema) {\r\n issues.push({\r\n code: \"UNKNOWN_PROFILE\",\r\n path: \"/profiles\",\r\n message: `Profile \"${profileId}\" nao e um profile oficial PACP`,\r\n });\r\n continue;\r\n }\r\n\r\n const products = extractProducts(doc);\r\n const validateProfile = ajv.compile(profileSchema);\r\n\r\n for (let i = 0; i < products.length; i++) {\r\n const xFields = extractXFields(products[i]);\r\n if (Object.keys(xFields).length === 0) continue;\r\n\r\n const profileValid = validateProfile(xFields);\r\n if (!profileValid && validateProfile.errors) {\r\n for (const error of validateProfile.errors) {\r\n issues.push({\r\n code: \"PROFILE_VALIDATION\",\r\n path: `products[${i}]${error.instancePath || \"/\"}`,\r\n message: `Profile \"${profileId}\": ${error.message ?? \"erro de validacao\"}`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n\r\nfunction extractProducts(doc: Record<string, unknown>): Record<string, unknown>[] {\r\n if (doc.document_type === \"PRODUCT\" && doc.product && typeof doc.product === \"object\") {\r\n return [doc.product as Record<string, unknown>];\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractXFields(obj: Record<string, unknown>): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (key.startsWith(\"x-\")) {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/validate.ts"],"sourcesContent":["export { schema, profiles, profileIds } from \"./schema.js\";\r\nexport { validate } from \"./validate.js\";\r\nexport type {\r\n ScalarValue,\r\n ImageType,\r\n Image,\r\n Measure,\r\n PhysicalDimensions,\r\n AttributeRef,\r\n AttributeValue,\r\n Option,\r\n LotPolicy,\r\n SalesUnit,\r\n SourceWhen,\r\n SuppliedMaterial,\r\n SuppliedMaterialCost,\r\n SuppliedMaterialQuantity,\r\n SuppliedMaterialSource,\r\n SupplyOutputEntry,\r\n Product,\r\n Predicate,\r\n Condition,\r\n Component,\r\n RuleOperation,\r\n Rule,\r\n Ruleset,\r\n LookupAxis,\r\n TableRow,\r\n Table,\r\n Dependency,\r\n Constraint,\r\n PriceList,\r\n Catalog,\r\n ProductRef,\r\n Context,\r\n Pricing,\r\n CatalogDocument,\r\n ProductDocument,\r\n PacpDocument,\r\n ProfileId,\r\n ValidationIssue,\r\n ValidationResult,\r\n} from \"./types.js\";\r\n","import { readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nfunction loadJson(relativePath: string): Record<string, unknown> {\r\n const fullPath = join(__dirname, relativePath);\r\n return JSON.parse(readFileSync(fullPath, \"utf8\"));\r\n}\r\n\r\nexport const schema = loadJson(\"./pacp.schema.json\") as Record<string, unknown>;\r\n\r\nexport const profiles = {\r\n moveis: loadJson(\"./profiles/moveis.schema.json\") as Record<string, unknown>,\r\n iluminacao: loadJson(\"./profiles/iluminacao.schema.json\") as Record<string, unknown>,\r\n \"pisos-revestimentos\": loadJson(\"./profiles/pisos-revestimentos.schema.json\") as Record<string, unknown>,\r\n \"fiscal-br\": loadJson(\"./profiles/fiscal-br.schema.json\") as Record<string, unknown>,\r\n} as const;\r\n\r\nexport type ProfileId = keyof typeof profiles;\r\n\r\nexport const profileIds = Object.keys(profiles) as ProfileId[];\r\n","import type { ValidationResult, ValidationIssue, PacpDocument } from \"./types.js\";\r\nimport { schema, profiles, type ProfileId } from \"./schema.js\";\r\n\r\nexport function validate(document: unknown): ValidationResult {\r\n let Ajv2020: typeof import(\"ajv/dist/2020\").default;\r\n let addFormats: typeof import(\"ajv-formats\").default;\r\n\r\n try {\r\n Ajv2020 = require(\"ajv/dist/2020\") as typeof import(\"ajv/dist/2020\").default;\r\n addFormats = require(\"ajv-formats\") as typeof import(\"ajv-formats\").default;\r\n } catch {\r\n throw new Error(\r\n 'Para usar validate(), instale ajv e ajv-formats: npm install ajv ajv-formats'\r\n );\r\n }\r\n\r\n const ajv = new Ajv2020({ allErrors: true, strict: false });\r\n addFormats(ajv);\r\n\r\n const issues: ValidationIssue[] = [];\r\n\r\n const validateSchema = ajv.compile(schema);\r\n const valid = validateSchema(document);\r\n\r\n if (!valid && validateSchema.errors) {\r\n for (const error of validateSchema.errors) {\r\n issues.push({\r\n code: \"SCHEMA\",\r\n path: error.instancePath || \"/\",\r\n message: error.message ?? \"Erro de validacao de schema\",\r\n });\r\n }\r\n }\r\n\r\n if (document && typeof document === \"object\" && !Array.isArray(document)) {\r\n const doc = document as Record<string, unknown>;\r\n const declaredProfiles = Array.isArray(doc.profiles) ? doc.profiles : [];\r\n\r\n for (const profileId of declaredProfiles) {\r\n if (typeof profileId !== \"string\") continue;\r\n\r\n const profileSchema = profiles[profileId as ProfileId];\r\n if (!profileSchema) {\r\n issues.push({\r\n code: \"UNKNOWN_PROFILE\",\r\n path: \"/profiles\",\r\n message: `Profile \"${profileId}\" nao e um profile oficial PACP`,\r\n });\r\n continue;\r\n }\r\n\r\n const products = extractProducts(doc);\r\n const validateProfile = ajv.compile(profileSchema);\r\n\r\n for (let i = 0; i < products.length; i++) {\r\n const xFields = extractXFields(products[i]);\r\n if (Object.keys(xFields).length === 0) continue;\r\n\r\n const profileValid = validateProfile(xFields);\r\n if (!profileValid && validateProfile.errors) {\r\n for (const error of validateProfile.errors) {\r\n issues.push({\r\n code: \"PROFILE_VALIDATION\",\r\n path: `products[${i}]${error.instancePath || \"/\"}`,\r\n message: `Profile \"${profileId}\": ${error.message ?? \"erro de validacao\"}`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n\r\nfunction extractProducts(doc: Record<string, unknown>): Record<string, unknown>[] {\r\n if (doc.document_type === \"PRODUCT\" && doc.product && typeof doc.product === \"object\") {\r\n return [doc.product as Record<string, unknown>];\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractXFields(obj: Record<string, unknown>): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (key.startsWith(\"x-\")) {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -48,19 +48,63 @@ interface SalesUnit {
48
48
  rounding: "CEIL" | "FLOOR" | "ROUND" | "HALF_UP";
49
49
  min_sell_units?: number;
50
50
  }
51
+ type SuppliedMaterialSource = "FACTORY" | "CUSTOMER";
52
+ interface SuppliedMaterialQuantityValue {
53
+ value: number;
54
+ unit: string;
55
+ }
56
+ interface SuppliedMaterialQuantityTable {
57
+ table_id: string;
58
+ unit: string;
59
+ }
60
+ type SuppliedMaterialQuantity = SuppliedMaterialQuantityValue | SuppliedMaterialQuantityTable;
61
+ interface SuppliedMaterialCostValue {
62
+ value: number;
63
+ }
64
+ interface SuppliedMaterialCostTable {
65
+ table_id: string;
66
+ }
67
+ interface SuppliedMaterialCostRuleset {
68
+ ruleset_id: string;
69
+ }
70
+ type SuppliedMaterialCost = SuppliedMaterialCostValue | SuppliedMaterialCostTable | SuppliedMaterialCostRuleset;
71
+ interface SourceWhen {
72
+ factory: ScalarValue[];
73
+ customer: ScalarValue[];
74
+ }
75
+ interface SuppliedMaterial {
76
+ id: string;
77
+ material: string;
78
+ quantity: SuppliedMaterialQuantity;
79
+ default_source?: SuppliedMaterialSource;
80
+ sourcing_attribute_id?: string;
81
+ source_when?: SourceWhen;
82
+ factory_cost?: SuppliedMaterialCost;
83
+ requirements?: Record<string, unknown>;
84
+ [key: `x-${string}`]: unknown;
85
+ }
86
+ interface SupplyOutputEntry {
87
+ material_id: string;
88
+ material: string;
89
+ quantity: number;
90
+ unit: string;
91
+ requirements?: Record<string, unknown>;
92
+ }
51
93
  interface Product {
52
94
  id: string;
53
95
  name?: string;
96
+ visibility?: "PUBLIC" | "INTERNAL";
54
97
  sku?: string;
55
98
  manufacturer?: string;
56
99
  brand?: string;
57
100
  description?: string;
58
- category?: string;
101
+ category?: string[][];
59
102
  gtin?: string;
60
103
  base_price?: number;
61
104
  unit?: string;
62
105
  images?: Image[];
63
106
  tags?: string[];
107
+ collections?: string[];
64
108
  weight?: Measure;
65
109
  dimensions?: PhysicalDimensions;
66
110
  lot_policy?: LotPolicy;
@@ -68,6 +112,7 @@ interface Product {
68
112
  attributes?: AttributeRef[];
69
113
  attribute_values?: AttributeValue[];
70
114
  options: Option[];
115
+ supplied_materials?: SuppliedMaterial[];
71
116
  ruleset_ids?: string[];
72
117
  [key: `x-${string}`]: unknown;
73
118
  }
@@ -215,4 +260,4 @@ interface ValidationResult {
215
260
 
216
261
  declare function validate(document: unknown): ValidationResult;
217
262
 
218
- export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Image, type ImageType, type LookupAxis, type LotPolicy, type Measure, type Option, type PacpDocument, type PhysicalDimensions, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, type SalesUnit, type ScalarValue, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
263
+ export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Image, type ImageType, type LookupAxis, type LotPolicy, type Measure, type Option, type PacpDocument, type PhysicalDimensions, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, type SalesUnit, type ScalarValue, type SourceWhen, type SuppliedMaterial, type SuppliedMaterialCost, type SuppliedMaterialQuantity, type SuppliedMaterialSource, type SupplyOutputEntry, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
package/dist/index.d.ts CHANGED
@@ -48,19 +48,63 @@ interface SalesUnit {
48
48
  rounding: "CEIL" | "FLOOR" | "ROUND" | "HALF_UP";
49
49
  min_sell_units?: number;
50
50
  }
51
+ type SuppliedMaterialSource = "FACTORY" | "CUSTOMER";
52
+ interface SuppliedMaterialQuantityValue {
53
+ value: number;
54
+ unit: string;
55
+ }
56
+ interface SuppliedMaterialQuantityTable {
57
+ table_id: string;
58
+ unit: string;
59
+ }
60
+ type SuppliedMaterialQuantity = SuppliedMaterialQuantityValue | SuppliedMaterialQuantityTable;
61
+ interface SuppliedMaterialCostValue {
62
+ value: number;
63
+ }
64
+ interface SuppliedMaterialCostTable {
65
+ table_id: string;
66
+ }
67
+ interface SuppliedMaterialCostRuleset {
68
+ ruleset_id: string;
69
+ }
70
+ type SuppliedMaterialCost = SuppliedMaterialCostValue | SuppliedMaterialCostTable | SuppliedMaterialCostRuleset;
71
+ interface SourceWhen {
72
+ factory: ScalarValue[];
73
+ customer: ScalarValue[];
74
+ }
75
+ interface SuppliedMaterial {
76
+ id: string;
77
+ material: string;
78
+ quantity: SuppliedMaterialQuantity;
79
+ default_source?: SuppliedMaterialSource;
80
+ sourcing_attribute_id?: string;
81
+ source_when?: SourceWhen;
82
+ factory_cost?: SuppliedMaterialCost;
83
+ requirements?: Record<string, unknown>;
84
+ [key: `x-${string}`]: unknown;
85
+ }
86
+ interface SupplyOutputEntry {
87
+ material_id: string;
88
+ material: string;
89
+ quantity: number;
90
+ unit: string;
91
+ requirements?: Record<string, unknown>;
92
+ }
51
93
  interface Product {
52
94
  id: string;
53
95
  name?: string;
96
+ visibility?: "PUBLIC" | "INTERNAL";
54
97
  sku?: string;
55
98
  manufacturer?: string;
56
99
  brand?: string;
57
100
  description?: string;
58
- category?: string;
101
+ category?: string[][];
59
102
  gtin?: string;
60
103
  base_price?: number;
61
104
  unit?: string;
62
105
  images?: Image[];
63
106
  tags?: string[];
107
+ collections?: string[];
64
108
  weight?: Measure;
65
109
  dimensions?: PhysicalDimensions;
66
110
  lot_policy?: LotPolicy;
@@ -68,6 +112,7 @@ interface Product {
68
112
  attributes?: AttributeRef[];
69
113
  attribute_values?: AttributeValue[];
70
114
  options: Option[];
115
+ supplied_materials?: SuppliedMaterial[];
71
116
  ruleset_ids?: string[];
72
117
  [key: `x-${string}`]: unknown;
73
118
  }
@@ -215,4 +260,4 @@ interface ValidationResult {
215
260
 
216
261
  declare function validate(document: unknown): ValidationResult;
217
262
 
218
- export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Image, type ImageType, type LookupAxis, type LotPolicy, type Measure, type Option, type PacpDocument, type PhysicalDimensions, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, type SalesUnit, type ScalarValue, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
263
+ export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Image, type ImageType, type LookupAxis, type LotPolicy, type Measure, type Option, type PacpDocument, type PhysicalDimensions, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, type SalesUnit, type ScalarValue, type SourceWhen, type SuppliedMaterial, type SuppliedMaterialCost, type SuppliedMaterialQuantity, type SuppliedMaterialSource, type SupplyOutputEntry, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://cdn.jsdelivr.net/npm/@pacp/spec@latest/dist/pacp.schema.json",
4
- "title": "PACP v3.1.0",
4
+ "title": "PACP v3.4.0",
5
5
  "oneOf": [
6
6
  {
7
7
  "$ref": "#/$defs/catalog_document"
@@ -298,6 +298,14 @@
298
298
  "name": {
299
299
  "type": "string"
300
300
  },
301
+ "visibility": {
302
+ "type": "string",
303
+ "enum": [
304
+ "PUBLIC",
305
+ "INTERNAL"
306
+ ],
307
+ "default": "PUBLIC"
308
+ },
301
309
  "sku": {
302
310
  "type": "string",
303
311
  "minLength": 1
@@ -323,7 +331,7 @@
323
331
  },
324
332
  "minItems": 1
325
333
  },
326
- "description": "Categorias hierárquicas do produto. Cada item é um path da raiz à folha, ex.: [[\"Móveis\", \"Sofá\"], [\"Promoções\"]]."
334
+ "description": "Categorias hier\u00e1rquicas do produto. Cada item \u00e9 um path da raiz \u00e0 folha, ex.: [[\"M\u00f3veis\", \"Sof\u00e1\"], [\"Promo\u00e7\u00f5es\"]]."
327
335
  },
328
336
  "gtin": {
329
337
  "type": "string",
@@ -349,6 +357,15 @@
349
357
  "minLength": 1
350
358
  }
351
359
  },
360
+ "collections": {
361
+ "type": "array",
362
+ "uniqueItems": true,
363
+ "items": {
364
+ "type": "string",
365
+ "minLength": 1
366
+ },
367
+ "description": "Identificadores de cole\u00e7\u00f5es \u00e0s quais o produto pertence (ex.: \"verao_2026\", \"linha_premium\"). Cada item \u00e9 um ID est\u00e1vel, \u00fanico por cat\u00e1logo, com sem\u00e2ntica de agrupamento curatorial/sazonal."
368
+ },
352
369
  "weight": {
353
370
  "$ref": "#/$defs/measure"
354
371
  },
@@ -379,6 +396,13 @@
379
396
  "$ref": "#/$defs/option"
380
397
  }
381
398
  },
399
+ "supplied_materials": {
400
+ "type": "array",
401
+ "items": {
402
+ "$ref": "#/$defs/supplied_material"
403
+ },
404
+ "description": "Materiais consumidos pelo produto, com sourcing factory/customer. Ver se\u00e7\u00e3o 4.8."
405
+ },
382
406
  "ruleset_ids": {
383
407
  "type": "array",
384
408
  "items": {
@@ -1166,7 +1190,7 @@
1166
1190
  "position": {
1167
1191
  "type": "integer",
1168
1192
  "minimum": 0,
1169
- "description": "Ordem explícita de exibição; quando presente, consumidores DEVEM ordenar por position crescente."
1193
+ "description": "Ordem expl\u00edcita de exibi\u00e7\u00e3o; quando presente, consumidores DEVEM ordenar por position crescente."
1170
1194
  },
1171
1195
  "type": {
1172
1196
  "type": "string",
@@ -1235,6 +1259,239 @@
1235
1259
  "number",
1236
1260
  "boolean"
1237
1261
  ]
1262
+ },
1263
+ "supplied_material_quantity": {
1264
+ "type": "object",
1265
+ "additionalProperties": false,
1266
+ "patternProperties": {
1267
+ "^x-": true
1268
+ },
1269
+ "properties": {
1270
+ "value": {
1271
+ "type": "number",
1272
+ "exclusiveMinimum": 0
1273
+ },
1274
+ "table_id": {
1275
+ "type": "string",
1276
+ "minLength": 1
1277
+ },
1278
+ "unit": {
1279
+ "type": "string",
1280
+ "minLength": 1
1281
+ }
1282
+ },
1283
+ "required": [
1284
+ "unit"
1285
+ ],
1286
+ "oneOf": [
1287
+ {
1288
+ "required": [
1289
+ "value"
1290
+ ],
1291
+ "not": {
1292
+ "required": [
1293
+ "table_id"
1294
+ ]
1295
+ }
1296
+ },
1297
+ {
1298
+ "required": [
1299
+ "table_id"
1300
+ ],
1301
+ "not": {
1302
+ "required": [
1303
+ "value"
1304
+ ]
1305
+ }
1306
+ }
1307
+ ],
1308
+ "description": "Quantidade de insumo necess\u00e1ria. Aceita value fixo (number > 0) OU table_id (lookup). Sempre exige unit."
1309
+ },
1310
+ "supplied_material_cost": {
1311
+ "type": "object",
1312
+ "additionalProperties": false,
1313
+ "patternProperties": {
1314
+ "^x-": true
1315
+ },
1316
+ "properties": {
1317
+ "value": {
1318
+ "type": "number",
1319
+ "minimum": 0
1320
+ },
1321
+ "table_id": {
1322
+ "type": "string",
1323
+ "minLength": 1
1324
+ },
1325
+ "ruleset_id": {
1326
+ "type": "string",
1327
+ "minLength": 1
1328
+ }
1329
+ },
1330
+ "oneOf": [
1331
+ {
1332
+ "required": [
1333
+ "value"
1334
+ ],
1335
+ "not": {
1336
+ "anyOf": [
1337
+ {
1338
+ "required": [
1339
+ "table_id"
1340
+ ]
1341
+ },
1342
+ {
1343
+ "required": [
1344
+ "ruleset_id"
1345
+ ]
1346
+ }
1347
+ ]
1348
+ }
1349
+ },
1350
+ {
1351
+ "required": [
1352
+ "table_id"
1353
+ ],
1354
+ "not": {
1355
+ "anyOf": [
1356
+ {
1357
+ "required": [
1358
+ "value"
1359
+ ]
1360
+ },
1361
+ {
1362
+ "required": [
1363
+ "ruleset_id"
1364
+ ]
1365
+ }
1366
+ ]
1367
+ }
1368
+ },
1369
+ {
1370
+ "required": [
1371
+ "ruleset_id"
1372
+ ],
1373
+ "not": {
1374
+ "anyOf": [
1375
+ {
1376
+ "required": [
1377
+ "value"
1378
+ ]
1379
+ },
1380
+ {
1381
+ "required": [
1382
+ "table_id"
1383
+ ]
1384
+ }
1385
+ ]
1386
+ }
1387
+ }
1388
+ ],
1389
+ "description": "Custo do material quando fonte=FACTORY. Exatamente um de value, table_id ou ruleset_id."
1390
+ },
1391
+ "source_when": {
1392
+ "type": "object",
1393
+ "additionalProperties": false,
1394
+ "patternProperties": {
1395
+ "^x-": true
1396
+ },
1397
+ "required": [
1398
+ "factory",
1399
+ "customer"
1400
+ ],
1401
+ "properties": {
1402
+ "factory": {
1403
+ "type": "array",
1404
+ "minItems": 1,
1405
+ "uniqueItems": true,
1406
+ "items": {
1407
+ "type": [
1408
+ "string",
1409
+ "number",
1410
+ "boolean"
1411
+ ]
1412
+ }
1413
+ },
1414
+ "customer": {
1415
+ "type": "array",
1416
+ "minItems": 1,
1417
+ "uniqueItems": true,
1418
+ "items": {
1419
+ "type": [
1420
+ "string",
1421
+ "number",
1422
+ "boolean"
1423
+ ]
1424
+ }
1425
+ }
1426
+ },
1427
+ "description": "Mapeia option.value -> modo de sourcing. Cada valor da option do attribute referenciado por sourcing_attribute_id deve aparecer em factory[] OU customer[]."
1428
+ },
1429
+ "supplied_material": {
1430
+ "type": "object",
1431
+ "additionalProperties": false,
1432
+ "patternProperties": {
1433
+ "^x-": true
1434
+ },
1435
+ "required": [
1436
+ "id",
1437
+ "material",
1438
+ "quantity"
1439
+ ],
1440
+ "properties": {
1441
+ "id": {
1442
+ "type": "string",
1443
+ "minLength": 1
1444
+ },
1445
+ "material": {
1446
+ "type": "string",
1447
+ "minLength": 1,
1448
+ "pattern": "^[A-Z][A-Z0-9_]*$"
1449
+ },
1450
+ "quantity": {
1451
+ "$ref": "#/$defs/supplied_material_quantity"
1452
+ },
1453
+ "default_source": {
1454
+ "type": "string",
1455
+ "enum": [
1456
+ "FACTORY",
1457
+ "CUSTOMER"
1458
+ ],
1459
+ "default": "FACTORY"
1460
+ },
1461
+ "sourcing_attribute_id": {
1462
+ "type": "string",
1463
+ "minLength": 1
1464
+ },
1465
+ "source_when": {
1466
+ "$ref": "#/$defs/source_when"
1467
+ },
1468
+ "factory_cost": {
1469
+ "$ref": "#/$defs/supplied_material_cost"
1470
+ },
1471
+ "requirements": {
1472
+ "type": "object",
1473
+ "additionalProperties": true,
1474
+ "patternProperties": {
1475
+ "^x-": true
1476
+ },
1477
+ "description": "Bloco livre de requisitos do material. Profiles podem padronizar subgrupos como x-fabric_requirements."
1478
+ }
1479
+ },
1480
+ "allOf": [
1481
+ {
1482
+ "if": {
1483
+ "required": [
1484
+ "sourcing_attribute_id"
1485
+ ]
1486
+ },
1487
+ "then": {
1488
+ "required": [
1489
+ "source_when"
1490
+ ]
1491
+ }
1492
+ }
1493
+ ],
1494
+ "description": "Insumo consumido pelo produto, com regra de quem fornece (f\u00e1brica ou cliente). Ver se\u00e7\u00e3o 4.8 da spec."
1238
1495
  }
1239
1496
  }
1240
- }
1497
+ }
@@ -37,6 +37,25 @@
37
37
  "type": "string",
38
38
  "enum": ["INDOOR", "OUTDOOR", "BOTH"],
39
39
  "description": "Indicacao de uso interno, externo ou ambos."
40
+ },
41
+ "x-fabric_requirements": {
42
+ "type": "object",
43
+ "additionalProperties": true,
44
+ "properties": {
45
+ "min_weight_gsm": { "type": "number", "exclusiveMinimum": 0, "description": "Gramatura mínima do tecido (g/m²)." },
46
+ "max_weight_gsm": { "type": "number", "exclusiveMinimum": 0, "description": "Gramatura máxima do tecido (g/m²)." },
47
+ "min_width_cm": { "type": "number", "exclusiveMinimum": 0, "description": "Largura mínima do rolo (cm)." },
48
+ "allowed_compositions": {
49
+ "type": "array",
50
+ "minItems": 1,
51
+ "uniqueItems": true,
52
+ "items": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]*$" },
53
+ "description": "Composições aceitas (uppercase, ex: LINHO, ALGODAO, VELUDO)."
54
+ },
55
+ "abrasion_min_cycles_martindale": { "type": "integer", "minimum": 0, "description": "Resistência mínima à abrasão (ciclos Martindale)." },
56
+ "flammability_standard": { "type": "string", "minLength": 1, "description": "Norma de inflamabilidade exigida (ex: NBR_15805)." }
57
+ },
58
+ "description": "Requisitos para tecido fornecido pelo cliente. Usado dentro de supplied_materials[].requirements."
40
59
  }
41
60
  },
42
61
  "additionalProperties": true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pacp/spec",
3
- "version": "3.1.0",
3
+ "version": "3.4.0",
4
4
  "description": "PACP - Padrão Aberto de Catálogo e Precificação. Schema, profiles e validador para catálogos de produtos.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",