{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://git.sr.ht/~danprobst/kinsaga/schema.json",
"title": "Kinsaga Chronicle",
"description": "A family chronicle containing categorized life events for multiple persons",
"type": "object",
"required": ["version", "categories", "persons"],
"properties": {
"version": {
"type": "string",
"description": "Schema version",
"const": "1.0"
},
"title": {
"type": "string",
"description": "Optional title for the chronicle"
},
"last_updated": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp of last modification (auto-set on save)"
},
"categories": {
"type": "array",
"description": "User-defined event categories",
"items": {
"$ref": "#/definitions/Category"
}
},
"persons": {
"type": "array",
"description": "People in the chronicle",
"items": {
"$ref": "#/definitions/Person"
}
}
},
"definitions": {
"Category": {
"type": "object",
"description": "A category for classifying facts/events",
"required": ["id", "label"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the category (used in facts)",
"pattern": "^[a-z][a-z0-9_-]*$",
"examples": ["education", "family", "travel", "work"]
},
"label": {
"type": "string",
"description": "Human-readable display name",
"minLength": 1,
"examples": ["Education & Job", "Family", "Travel"]
},
"color": {
"type": "string",
"description": "Optional hex color for UI display",
"pattern": "^#[0-9A-Fa-f]{6}$",
"examples": ["#4A90D9", "#D94A4A"]
}
}
},
"Person": {
"type": "object",
"description": "A person in the chronicle",
"required": ["id", "name", "facts"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the person",
"pattern": "^[a-z][a-z0-9_-]*$",
"examples": ["alice", "bob", "john-doe"]
},
"name": {
"type": "string",
"description": "Full display name",
"minLength": 1,
"examples": ["Alice Smith", "Bob Johnson"]
},
"facts": {
"type": "array",
"description": "Life events for this person",
"items": {
"$ref": "#/definitions/Fact"
}
}
}
},
"Fact": {
"type": "object",
"description": "A life event or fact about a person",
"required": ["id", "date", "category", "text"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier (UUID v4)",
"format": "uuid",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
"examples": ["550e8400-e29b-41d4-a716-446655440000"]
},
"date": {
"type": "string",
"description": "Date in ISO 8601 format with optional ? suffix for uncertainty",
"pattern": "^\\d{4}(-\\d{2}(-\\d{2})?)?\\??$",
"examples": ["1987", "1987-03", "1987-03-15", "1987?", "1987-03?"]
},
"category": {
"type": "string",
"description": "Reference to a category id",
"pattern": "^[a-z][a-z0-9_-]*$"
},
"text": {
"type": "string",
"description": "Description of the event",
"minLength": 1
},
"with": {
"type": "array",
"description": "Other person ids involved in this event",
"items": {
"type": "string",
"pattern": "^[a-z][a-z0-9_-]*$"
}
},
"location": {
"$ref": "#/definitions/Location"
},
"attachments": {
"type": "array",
"description": "Related files or media",
"items": {
"$ref": "#/definitions/Attachment"
},
"default": []
}
}
},
"Location": {
"type": "object",
"description": "Geographic location of an event",
"required": ["country"],
"properties": {
"country": {
"type": "string",
"description": "Country name or ISO code",
"minLength": 1,
"examples": ["France", "USA", "DE"]
},
"place": {
"type": "string",
"description": "Place name (city, address, landmark, venue, etc.)",
"examples": ["Paris", "Rifugio Auronzo", "123 Main Street, Springfield", "Eiffel Tower"]
},
"coordinates": {
"$ref": "#/definitions/Coordinates"
}
}
},
"Coordinates": {
"type": "object",
"description": "GPS coordinates",
"required": ["lat", "lon"],
"properties": {
"lat": {
"type": "number",
"description": "Latitude in decimal degrees",
"minimum": -90,
"maximum": 90,
"examples": [48.8566, -33.8688]
},
"lon": {
"type": "number",
"description": "Longitude in decimal degrees",
"minimum": -180,
"maximum": 180,
"examples": [2.3522, 151.2093]
}
}
},
"Attachment": {
"type": "object",
"description": "A file or media attachment",
"required": ["url"],
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "URL with scheme (file://, https://, s3://, etc.)",
"examples": [
"file:///photos/event.jpg",
"https://example.com/doc.pdf",
"s3://bucket/path/image.png"
]
},
"content_type": {
"type": "string",
"description": "MIME type",
"pattern": "^[a-zA-Z0-9.+-]+/[a-zA-Z0-9.+-]+$",
"examples": ["image/jpeg", "application/pdf", "video/mp4"]
},
"title": {
"type": "string",
"description": "Human-readable description",
"examples": ["Wedding photo", "Birth certificate"]
}
}
}
}
}