{ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://familybudget.example.com/schemas/frontend-validation.schema.json", "title": "Frontend Component Validation Schema", "description": "JSON Schema for validating frontend component structure in Family Budget project", "type": "object", "properties": { "component": { "type": "object", "properties": { "type": { "type": "string", "enum": ["modal", "page", "card", "form", "list"], "description": "Component type" }, "template": { "type": "string", "description": "Jinja2 template file path", "pattern": "^frontend/web/templates/.+\\.html$" }, "javascript": { "type": "array", "items": { "type": "string", "pattern": "^frontend/web/static/js/.+\\.js$" }, "description": "JavaScript module dependencies" }, "htmx": { "type": "object", "properties": { "enabled": { "type": "boolean", "description": "HTMX enabled for this component" }, "endpoints": { "type": "array", "items": { "type": "object", "properties": { "url": { "type": "string", "pattern": "^/api/v1/.+$" }, "trigger": { "type": "string", "enum": ["load", "click", "change", "submit", "revealed", "intersect"] }, "swap": { "type": "string", "enum": ["innerHTML", "outerHTML", "beforebegin", "afterbegin", "beforeend", "afterend", "delete", "none"] } }, "required": ["url", "trigger"] } } } }, "websocket": { "type": "object", "properties": { "enabled": { "type": "boolean" }, "events": { "type": "array", "items": { "type": "string", "description": "WebSocket event names (e.g., budget_fact_created)" } } } }, "validation": { "type": "object", "properties": { "tailwind_used": { "type": "boolean", "description": "Tailwind CSS utility classes used (NO custom CSS)" }, "daisyui_components": { "type": "array", "items": { "type": "string", "enum": ["modal", "card", "btn", "input", "select", "textarea", "checkbox", "radio", "badge", "alert", "loading", "dropdown", "navbar", "footer"] } }, "responsive": { "type": "boolean", "description": "Mobile-first responsive design (md:, lg: breakpoints)" }, "accessibility": { "type": "object", "properties": { "aria_labels": { "type": "boolean" }, "keyboard_navigation": { "type": "boolean" }, "focus_management": { "type": "boolean" } } } }, "required": ["tailwind_used", "responsive"] } }, "required": ["type", "template", "validation"] } }, "required": ["component"], "examples": [ { "component": { "type": "modal", "template": "frontend/web/templates/components/modal_transaction.html", "javascript": [ "frontend/web/static/js/budget/transactionForm.js" ], "htmx": { "enabled": true, "endpoints": [ { "url": "/api/v1/facts/recent", "trigger": "load", "swap": "innerHTML" } ] }, "websocket": { "enabled": true, "events": [ "budget_fact_created", "budget_fact_updated", "budget_fact_deleted" ] }, "validation": { "tailwind_used": true, "daisyui_components": [ "modal", "btn", "input", "select" ], "responsive": true, "accessibility": { "aria_labels": true, "keyboard_navigation": true, "focus_management": true } } } } ] }