@pacp/spec 3.4.2 → 3.6.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/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/pacp.schema.json +144 -8
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -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 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":[]}
|
|
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 ProductRole,\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
|
@@ -238,6 +238,18 @@ interface SupplyOutputEntry {
|
|
|
238
238
|
/** Requisitos copiados do `SuppliedMaterial.requirements`. */
|
|
239
239
|
requirements?: Record<string, unknown>;
|
|
240
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Papel do produto na hierarquia família/módulo. Ver spec §4.9.
|
|
243
|
+
*
|
|
244
|
+
* - `STANDALONE` (default quando ausente): produto vendido independentemente — comportamento PACP histórico.
|
|
245
|
+
* - `FAMILY`: agrupador conceitual sem SKU/preço próprios (ex.: linha de sofá modular ADANA).
|
|
246
|
+
* Não pode ter `base_price` nem `family_product_id`. Pode listar seus módulos em `member_product_ids`.
|
|
247
|
+
* - `MODULE`: componente vendável vinculado a uma FAMILY via `family_product_id` (obrigatório).
|
|
248
|
+
* Tem `base_price` próprio. Pode marcar `standalone_sellable=false` se só for vendido como parte da composição.
|
|
249
|
+
*
|
|
250
|
+
* Profundidade da hierarquia é 1 (FAMILY não pode ter `family_product_id`).
|
|
251
|
+
*/
|
|
252
|
+
type ProductRole = "STANDALONE" | "FAMILY" | "MODULE";
|
|
241
253
|
/**
|
|
242
254
|
* Produto único do catálogo. Ver spec §4.
|
|
243
255
|
*
|
|
@@ -306,6 +318,14 @@ interface Product {
|
|
|
306
318
|
supplied_materials?: SuppliedMaterial[];
|
|
307
319
|
/** IDs de rulesets aplicados a este produto. */
|
|
308
320
|
ruleset_ids?: string[];
|
|
321
|
+
/** Papel do produto na hierarquia. Default implícito quando ausente: `STANDALONE`. Ver spec §4.9. */
|
|
322
|
+
role?: ProductRole;
|
|
323
|
+
/** ID da família (produto com `role="FAMILY"`) à qual este módulo pertence. Obrigatório quando `role="MODULE"`; proibido em outros casos. */
|
|
324
|
+
family_product_id?: string;
|
|
325
|
+
/** IDs dos módulos pertencentes a esta família. Permitido apenas quando `role="FAMILY"`. */
|
|
326
|
+
member_product_ids?: string[];
|
|
327
|
+
/** `false` quando o módulo só pode ser vendido como parte da composição da família. Default `true`. Permitido apenas quando `role="MODULE"`. */
|
|
328
|
+
standalone_sellable?: boolean;
|
|
309
329
|
[key: `x-${string}`]: unknown;
|
|
310
330
|
}
|
|
311
331
|
/**
|
|
@@ -475,6 +495,10 @@ interface PriceList {
|
|
|
475
495
|
interface Catalog {
|
|
476
496
|
id: string;
|
|
477
497
|
name?: string;
|
|
498
|
+
/** Observações públicas sobre o catálogo. Consumidores PODEM exibir. */
|
|
499
|
+
notes?: string;
|
|
500
|
+
/** Anotações não-públicas. Consumidores que geram catálogos públicos DEVEM omitir. Ver spec §9.1. */
|
|
501
|
+
internal_notes?: string;
|
|
478
502
|
default_price_list_id?: string;
|
|
479
503
|
price_lists?: PriceList[];
|
|
480
504
|
[key: `x-${string}`]: unknown;
|
|
@@ -564,4 +588,4 @@ interface ValidationResult {
|
|
|
564
588
|
|
|
565
589
|
declare function validate(document: unknown): ValidationResult;
|
|
566
590
|
|
|
567
|
-
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 };
|
|
591
|
+
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 ProductRole, 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
|
@@ -238,6 +238,18 @@ interface SupplyOutputEntry {
|
|
|
238
238
|
/** Requisitos copiados do `SuppliedMaterial.requirements`. */
|
|
239
239
|
requirements?: Record<string, unknown>;
|
|
240
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Papel do produto na hierarquia família/módulo. Ver spec §4.9.
|
|
243
|
+
*
|
|
244
|
+
* - `STANDALONE` (default quando ausente): produto vendido independentemente — comportamento PACP histórico.
|
|
245
|
+
* - `FAMILY`: agrupador conceitual sem SKU/preço próprios (ex.: linha de sofá modular ADANA).
|
|
246
|
+
* Não pode ter `base_price` nem `family_product_id`. Pode listar seus módulos em `member_product_ids`.
|
|
247
|
+
* - `MODULE`: componente vendável vinculado a uma FAMILY via `family_product_id` (obrigatório).
|
|
248
|
+
* Tem `base_price` próprio. Pode marcar `standalone_sellable=false` se só for vendido como parte da composição.
|
|
249
|
+
*
|
|
250
|
+
* Profundidade da hierarquia é 1 (FAMILY não pode ter `family_product_id`).
|
|
251
|
+
*/
|
|
252
|
+
type ProductRole = "STANDALONE" | "FAMILY" | "MODULE";
|
|
241
253
|
/**
|
|
242
254
|
* Produto único do catálogo. Ver spec §4.
|
|
243
255
|
*
|
|
@@ -306,6 +318,14 @@ interface Product {
|
|
|
306
318
|
supplied_materials?: SuppliedMaterial[];
|
|
307
319
|
/** IDs de rulesets aplicados a este produto. */
|
|
308
320
|
ruleset_ids?: string[];
|
|
321
|
+
/** Papel do produto na hierarquia. Default implícito quando ausente: `STANDALONE`. Ver spec §4.9. */
|
|
322
|
+
role?: ProductRole;
|
|
323
|
+
/** ID da família (produto com `role="FAMILY"`) à qual este módulo pertence. Obrigatório quando `role="MODULE"`; proibido em outros casos. */
|
|
324
|
+
family_product_id?: string;
|
|
325
|
+
/** IDs dos módulos pertencentes a esta família. Permitido apenas quando `role="FAMILY"`. */
|
|
326
|
+
member_product_ids?: string[];
|
|
327
|
+
/** `false` quando o módulo só pode ser vendido como parte da composição da família. Default `true`. Permitido apenas quando `role="MODULE"`. */
|
|
328
|
+
standalone_sellable?: boolean;
|
|
309
329
|
[key: `x-${string}`]: unknown;
|
|
310
330
|
}
|
|
311
331
|
/**
|
|
@@ -475,6 +495,10 @@ interface PriceList {
|
|
|
475
495
|
interface Catalog {
|
|
476
496
|
id: string;
|
|
477
497
|
name?: string;
|
|
498
|
+
/** Observações públicas sobre o catálogo. Consumidores PODEM exibir. */
|
|
499
|
+
notes?: string;
|
|
500
|
+
/** Anotações não-públicas. Consumidores que geram catálogos públicos DEVEM omitir. Ver spec §9.1. */
|
|
501
|
+
internal_notes?: string;
|
|
478
502
|
default_price_list_id?: string;
|
|
479
503
|
price_lists?: PriceList[];
|
|
480
504
|
[key: `x-${string}`]: unknown;
|
|
@@ -564,4 +588,4 @@ interface ValidationResult {
|
|
|
564
588
|
|
|
565
589
|
declare function validate(document: unknown): ValidationResult;
|
|
566
590
|
|
|
567
|
-
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 };
|
|
591
|
+
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 ProductRole, 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/pacp.schema.json
CHANGED
|
@@ -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.
|
|
4
|
+
"title": "PACP v3.6.0",
|
|
5
5
|
"oneOf": [
|
|
6
6
|
{
|
|
7
7
|
"$ref": "#/$defs/catalog_document"
|
|
@@ -183,6 +183,14 @@
|
|
|
183
183
|
"type": "string",
|
|
184
184
|
"minLength": 1
|
|
185
185
|
},
|
|
186
|
+
"notes": {
|
|
187
|
+
"type": "string",
|
|
188
|
+
"description": "Observações públicas sobre o catálogo (vigência, escopo, instruções de uso). Texto livre, multilinha permitido. Consumidores PODEM exibir."
|
|
189
|
+
},
|
|
190
|
+
"internal_notes": {
|
|
191
|
+
"type": "string",
|
|
192
|
+
"description": "Anotações internas (não-públicas) sobre o catálogo. Consumidores que geram vitrines/catálogos públicos DEVEM omitir este campo. Ver spec §9.1."
|
|
193
|
+
},
|
|
186
194
|
"default_price_list_id": {
|
|
187
195
|
"type": "string",
|
|
188
196
|
"minLength": 1
|
|
@@ -331,7 +339,7 @@
|
|
|
331
339
|
},
|
|
332
340
|
"minItems": 1
|
|
333
341
|
},
|
|
334
|
-
"description": "Categorias
|
|
342
|
+
"description": "Categorias hierárquicas do produto. Cada item é um path da raiz à folha, ex.: [[\"Móveis\", \"Sofá\"], [\"Promoções\"]]."
|
|
335
343
|
},
|
|
336
344
|
"gtin": {
|
|
337
345
|
"type": "string",
|
|
@@ -364,7 +372,7 @@
|
|
|
364
372
|
"type": "string",
|
|
365
373
|
"minLength": 1
|
|
366
374
|
},
|
|
367
|
-
"description": "Identificadores de
|
|
375
|
+
"description": "Identificadores de coleções às quais o produto pertence (ex.: \"verao_2026\", \"linha_premium\"). Cada item é um ID estável, único por catálogo, com semântica de agrupamento curatorial/sazonal."
|
|
368
376
|
},
|
|
369
377
|
"weight": {
|
|
370
378
|
"$ref": "#/$defs/measure"
|
|
@@ -401,7 +409,7 @@
|
|
|
401
409
|
"items": {
|
|
402
410
|
"$ref": "#/$defs/supplied_material"
|
|
403
411
|
},
|
|
404
|
-
"description": "Materiais consumidos pelo produto, com sourcing factory/customer. Ver
|
|
412
|
+
"description": "Materiais consumidos pelo produto, com sourcing factory/customer. Ver seção 4.8."
|
|
405
413
|
},
|
|
406
414
|
"ruleset_ids": {
|
|
407
415
|
"type": "array",
|
|
@@ -409,6 +417,35 @@
|
|
|
409
417
|
"type": "string",
|
|
410
418
|
"minLength": 1
|
|
411
419
|
}
|
|
420
|
+
},
|
|
421
|
+
"role": {
|
|
422
|
+
"type": "string",
|
|
423
|
+
"enum": [
|
|
424
|
+
"STANDALONE",
|
|
425
|
+
"FAMILY",
|
|
426
|
+
"MODULE"
|
|
427
|
+
],
|
|
428
|
+
"default": "STANDALONE",
|
|
429
|
+
"description": "Papel do produto na hierarquia. STANDALONE (default, retrocompatível) é vendido independentemente. FAMILY é agrupador conceitual sem SKU/preço próprios (ex.: linha de sofá modular). MODULE é componente vendável vinculado a uma FAMILY. Ver spec §4.9."
|
|
430
|
+
},
|
|
431
|
+
"family_product_id": {
|
|
432
|
+
"type": "string",
|
|
433
|
+
"minLength": 1,
|
|
434
|
+
"description": "Referência ao product.id de um produto com role=FAMILY no mesmo catalog document. Obrigatório quando role=MODULE; proibido para role=FAMILY ou STANDALONE."
|
|
435
|
+
},
|
|
436
|
+
"member_product_ids": {
|
|
437
|
+
"type": "array",
|
|
438
|
+
"items": {
|
|
439
|
+
"type": "string",
|
|
440
|
+
"minLength": 1
|
|
441
|
+
},
|
|
442
|
+
"uniqueItems": true,
|
|
443
|
+
"description": "Lista dos product.id dos módulos pertencentes a esta família. Emitido pelo materializer/exporter por conveniência do consumidor (evita scan); permitido apenas quando role=FAMILY."
|
|
444
|
+
},
|
|
445
|
+
"standalone_sellable": {
|
|
446
|
+
"type": "boolean",
|
|
447
|
+
"default": true,
|
|
448
|
+
"description": "Indica se um MODULE pode ser vendido isoladamente (true) ou apenas como parte de composição da família (false). Permitido apenas quando role=MODULE."
|
|
412
449
|
}
|
|
413
450
|
},
|
|
414
451
|
"allOf": [
|
|
@@ -439,6 +476,105 @@
|
|
|
439
476
|
}
|
|
440
477
|
}
|
|
441
478
|
}
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
"if": {
|
|
482
|
+
"properties": {
|
|
483
|
+
"role": {
|
|
484
|
+
"const": "MODULE"
|
|
485
|
+
}
|
|
486
|
+
},
|
|
487
|
+
"required": [
|
|
488
|
+
"role"
|
|
489
|
+
]
|
|
490
|
+
},
|
|
491
|
+
"then": {
|
|
492
|
+
"required": [
|
|
493
|
+
"family_product_id"
|
|
494
|
+
],
|
|
495
|
+
"not": {
|
|
496
|
+
"required": [
|
|
497
|
+
"member_product_ids"
|
|
498
|
+
]
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
"if": {
|
|
504
|
+
"properties": {
|
|
505
|
+
"role": {
|
|
506
|
+
"const": "FAMILY"
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
"required": [
|
|
510
|
+
"role"
|
|
511
|
+
]
|
|
512
|
+
},
|
|
513
|
+
"then": {
|
|
514
|
+
"not": {
|
|
515
|
+
"anyOf": [
|
|
516
|
+
{
|
|
517
|
+
"required": [
|
|
518
|
+
"family_product_id"
|
|
519
|
+
]
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
"required": [
|
|
523
|
+
"base_price"
|
|
524
|
+
]
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
"required": [
|
|
528
|
+
"standalone_sellable"
|
|
529
|
+
]
|
|
530
|
+
}
|
|
531
|
+
]
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"if": {
|
|
537
|
+
"anyOf": [
|
|
538
|
+
{
|
|
539
|
+
"properties": {
|
|
540
|
+
"role": {
|
|
541
|
+
"const": "STANDALONE"
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
"required": [
|
|
545
|
+
"role"
|
|
546
|
+
]
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
"not": {
|
|
550
|
+
"required": [
|
|
551
|
+
"role"
|
|
552
|
+
]
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
},
|
|
557
|
+
"then": {
|
|
558
|
+
"not": {
|
|
559
|
+
"anyOf": [
|
|
560
|
+
{
|
|
561
|
+
"required": [
|
|
562
|
+
"family_product_id"
|
|
563
|
+
]
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
"required": [
|
|
567
|
+
"member_product_ids"
|
|
568
|
+
]
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
"required": [
|
|
572
|
+
"standalone_sellable"
|
|
573
|
+
]
|
|
574
|
+
}
|
|
575
|
+
]
|
|
576
|
+
}
|
|
577
|
+
}
|
|
442
578
|
}
|
|
443
579
|
]
|
|
444
580
|
},
|
|
@@ -1190,7 +1326,7 @@
|
|
|
1190
1326
|
"position": {
|
|
1191
1327
|
"type": "integer",
|
|
1192
1328
|
"minimum": 0,
|
|
1193
|
-
"description": "Ordem
|
|
1329
|
+
"description": "Ordem explícita de exibição; quando presente, consumidores DEVEM ordenar por position crescente."
|
|
1194
1330
|
},
|
|
1195
1331
|
"type": {
|
|
1196
1332
|
"type": "string",
|
|
@@ -1305,7 +1441,7 @@
|
|
|
1305
1441
|
}
|
|
1306
1442
|
}
|
|
1307
1443
|
],
|
|
1308
|
-
"description": "Quantidade de insumo
|
|
1444
|
+
"description": "Quantidade de insumo necessária. Aceita value fixo (number > 0) OU table_id (lookup). Sempre exige unit."
|
|
1309
1445
|
},
|
|
1310
1446
|
"supplied_material_cost": {
|
|
1311
1447
|
"type": "object",
|
|
@@ -1491,7 +1627,7 @@
|
|
|
1491
1627
|
}
|
|
1492
1628
|
}
|
|
1493
1629
|
],
|
|
1494
|
-
"description": "Insumo consumido pelo produto, com regra de quem fornece (
|
|
1630
|
+
"description": "Insumo consumido pelo produto, com regra de quem fornece (fábrica ou cliente). Ver seção 4.8 da spec."
|
|
1495
1631
|
}
|
|
1496
1632
|
}
|
|
1497
|
-
}
|
|
1633
|
+
}
|
package/package.json
CHANGED