147 lines
4.6 KiB
JSON
147 lines
4.6 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://git.machinemachine.ai/m2/m2-market/schemas/listing.schema.json",
|
|
"title": "m2.listing.v1",
|
|
"description": "Catalog-facing projection of a marketplace listing. Forgejo m2/m2-market is truth; market:catalog is rebuildable.",
|
|
"type": "object",
|
|
"required": [
|
|
"schema_version",
|
|
"listing_id",
|
|
"solution_id",
|
|
"solution_version",
|
|
"inventory_type",
|
|
"name",
|
|
"summary",
|
|
"category",
|
|
"price",
|
|
"seller",
|
|
"content_hash",
|
|
"tenant_visibility",
|
|
"status",
|
|
"install_ref"
|
|
],
|
|
"properties": {
|
|
"schema_version": { "const": "m2.listing.v1" },
|
|
"listing_id": {
|
|
"type": "string",
|
|
"pattern": "^lst_[a-z0-9][a-z0-9-]*$"
|
|
},
|
|
"solution_id": {
|
|
"type": "string",
|
|
"pattern": "^sol_[a-z0-9][a-z0-9-]*$"
|
|
},
|
|
"solution_version": {
|
|
"type": "string",
|
|
"pattern": "^\\d+\\.\\d+\\.\\d+([+-][0-9A-Za-z.-]+)?$"
|
|
},
|
|
"inventory_type": {
|
|
"type": "string",
|
|
"enum": ["solution", "capability", "resource", "service"]
|
|
},
|
|
"name": { "type": "string", "minLength": 1 },
|
|
"summary": { "type": "string", "minLength": 1 },
|
|
"category": { "type": "string", "minLength": 1 },
|
|
"keywords": {
|
|
"type": "array",
|
|
"items": { "type": "string", "minLength": 1 },
|
|
"default": []
|
|
},
|
|
"icon": { "type": "string" },
|
|
"price": { "$ref": "#/$defs/price" },
|
|
"seller": { "$ref": "#/$defs/seller" },
|
|
"evidence_summary": { "type": "string" },
|
|
"content_hash": { "$ref": "#/$defs/sha256" },
|
|
"tenant_visibility": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": {
|
|
"type": "string",
|
|
"minLength": 1
|
|
},
|
|
"description": "Allowed tenants. [\"*\"] means public. Other values must be canonical tenant ids from contracts/tenants.md."
|
|
},
|
|
"stats": {
|
|
"type": "object",
|
|
"required": ["installs", "proposals_shown", "proposals_accepted"],
|
|
"properties": {
|
|
"installs": { "type": "integer", "minimum": 0, "default": 0 },
|
|
"rating": { "type": "number", "minimum": 0, "maximum": 5 },
|
|
"proposals_shown": { "type": "integer", "minimum": 0, "default": 0 },
|
|
"proposals_accepted": { "type": "integer", "minimum": 0, "default": 0 }
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["draft", "in_review", "published", "delisted"]
|
|
},
|
|
"install_ref": {
|
|
"type": "string",
|
|
"pattern": "^lst_[a-z0-9][a-z0-9-]*-v\\d+\\.\\d+\\.\\d+([+-][0-9A-Za-z.-]+)?$"
|
|
}
|
|
},
|
|
"additionalProperties": false,
|
|
"$defs": {
|
|
"sha256": {
|
|
"type": "string",
|
|
"pattern": "^sha256:[a-f0-9]{64}$"
|
|
},
|
|
"price": {
|
|
"oneOf": [
|
|
{
|
|
"type": "object",
|
|
"required": ["model", "amount", "currency"],
|
|
"properties": {
|
|
"model": { "const": "fixed" },
|
|
"amount": { "type": "integer", "minimum": 1 },
|
|
"currency": { "const": "m2cr" }
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
{
|
|
"type": "object",
|
|
"required": ["model", "currency", "quote", "settlement"],
|
|
"properties": {
|
|
"model": { "const": "job" },
|
|
"currency": { "const": "m2cr" },
|
|
"quote": {
|
|
"type": "object",
|
|
"required": ["min_amount", "max_amount", "expires_after_hours", "requires_acceptance"],
|
|
"properties": {
|
|
"min_amount": { "type": "integer", "minimum": 1 },
|
|
"max_amount": { "type": "integer", "minimum": 1 },
|
|
"expires_after_hours": { "type": "integer", "minimum": 1 },
|
|
"requires_acceptance": { "type": "boolean" }
|
|
},
|
|
"additionalProperties": false
|
|
},
|
|
"settlement": {
|
|
"type": "object",
|
|
"required": ["ledger_reason", "escrow_required"],
|
|
"properties": {
|
|
"ledger_reason": { "const": "job" },
|
|
"escrow_required": { "type": "boolean" }
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
]
|
|
},
|
|
"seller": {
|
|
"type": "object",
|
|
"required": ["operator_id", "display_name"],
|
|
"properties": {
|
|
"operator_id": {
|
|
"type": "string",
|
|
"pattern": "^op_[a-z0-9][a-z0-9-]*$"
|
|
},
|
|
"display_name": { "type": "string", "minLength": 1 },
|
|
"contact_ref": { "type": "string", "minLength": 1 },
|
|
"tenant_id": { "type": "string", "minLength": 1 }
|
|
},
|
|
"additionalProperties": false
|
|
}
|
|
}
|
|
}
|