tercul-backend/schemas/blog.json
google-labs-jules[bot] 4c2f20c33d feat: Implement blog schema and example content
This commit introduces a new blog feature by implementing a JSON schema for blog posts and providing five example content files.

Key changes:
- Created a new directory structure for schemas and content (`schemas/`, `content/blog/`).
- Implemented a JSON schema for blog posts, split into `blog.json` and `_defs.json` for reusability.
- Added five example blog post files with full, realistic content.
- Included a Python script (`validate.py`) to validate the example content against the schema.
2025-09-07 23:22:36 +00:00

240 lines
5.6 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/blog.json",
"title": "Blog Post",
"type": "object",
"additionalProperties": false,
"required": [
"contentTypeSlug",
"title",
"slug",
"status",
"content",
"languageCode",
"isDefault"
],
"properties": {
"contentTypeSlug": {
"type": "string",
"enum": ["blog"]
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"slug": {
"type": "string",
"pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
"minLength": 3,
"maxLength": 200
},
"status": {
"type": "string",
"enum": ["planned", "draft", "scheduled", "published", "archived"]
},
"content": {
"type": "object",
"additionalProperties": false,
"required": [
"excerpt",
"content",
"publishDate",
"author",
"tags",
"meta_title",
"meta_description"
],
"properties": {
"excerpt": {
"type": "string",
"minLength": 1
},
"content": {
"type": "string"
},
"publishDate": {
"type": "string",
"format": "date"
},
"author": {
"type": "string",
"minLength": 1
},
"tags": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"uniqueItems": false
},
"meta_title": {
"type": "string",
"minLength": 1
},
"meta_description": {
"type": "string",
"minLength": 1
}
}
},
"languageCode": {
"type": "string",
"pattern": "^[a-z]{2}(?:-[A-Z]{2})?$"
},
"isDefault": {
"type": "boolean"
},
"id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{3,200}$"
},
"translation_group_id": {
"type": "string",
"pattern": "^[a-zA-Z0-9_-]{3,200}$"
},
"lifecycle": {
"type": "object",
"additionalProperties": false,
"properties": {
"state": {
"type": "string",
"enum": ["planned", "draft", "scheduled", "published", "archived"]
},
"scheduled_at": {
"type": "string",
"format": "date-time"
},
"published_at": {
"type": "string",
"format": "date-time"
},
"timezone": {
"type": "string",
"minLength": 1
}
}
},
"seo": {
"type": "object",
"additionalProperties": false,
"properties": {
"canonical": {
"type": "string",
"format": "uri"
},
"og_title": {
"type": "string"
},
"og_description": {
"type": "string"
},
"og_image": {
"$ref": "_defs.json#/$defs/imageAsset"
},
"twitter_card": {
"type": "string",
"enum": ["summary", "summary_large_image"]
},
"json_ld": {
"type": "object",
"additionalProperties": true
}
}
},
"taxonomy": {
"type": "object",
"additionalProperties": false,
"properties": {
"categories": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
},
"series": {
"type": "string"
},
"featured": {
"type": "boolean"
},
"pin_until": {
"type": "string",
"format": "date-time"
}
}
},
"relations": {
"type": "object",
"additionalProperties": false,
"properties": {
"related_services": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
},
"related_posts": {
"type": "array",
"items": { "type": "string" },
"uniqueItems": true
}
}
},
"sources": {
"type": "array",
"items": {
"$ref": "_defs.json#/$defs/source"
}
},
"assets": {
"type": "object",
"additionalProperties": false,
"properties": {
"hero_image": {
"$ref": "_defs.json#/$defs/imageAsset"
},
"attachments": {
"type": "array",
"items": { "$ref": "_defs.json#/$defs/attachment" }
}
}
},
"audit": {
"type": "object",
"additionalProperties": false,
"properties": {
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" },
"created_by": { "type": "string" },
"updated_by": { "type": "string" },
"revision": { "type": "integer", "minimum": 0 },
"fact_checked": { "type": "boolean" },
"legal_reviewed": { "type": "boolean" },
"change_notes": { "type": "string" }
}
},
"metrics": {
"type": "object",
"additionalProperties": false,
"properties": {
"views": { "type": "integer", "minimum": 0 },
"avg_read_time_sec": { "type": "integer", "minimum": 0 },
"cta_clicks": { "type": "integer", "minimum": 0 }
}
},
"readability": {
"type": "object",
"additionalProperties": false,
"properties": {
"reading_time_minutes_est": { "type": "integer", "minimum": 0 },
"word_count": { "type": "integer", "minimum": 0 },
"summary_bullets": {
"type": "array",
"items": { "type": "string" },
"maxItems": 12
}
}
}
}
}