{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://corecore.local/schemas/module-manifest.schema.json", "title": "Module Manifest Schema", "description": "Declarative schema for module.php manifest files under modules//.", "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "minLength": 1, "pattern": "^[a-z][a-z0-9_-]*$", "description": "Module identifier — must match the directory name under modules/." }, "version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$", "description": "Semantic version (e.g. 1.0.0)." }, "enabled_by_default": { "type": "boolean", "default": false }, "load_order": { "type": "integer", "default": 100, "description": "Lower values load first. Deterministic tie-break by id ASC." }, "requires": { "type": "array", "items": { "type": "string", "minLength": 1 }, "uniqueItems": true, "default": [], "description": "Module IDs that must be enabled for this module to function." }, "routes": { "type": "array", "items": { "type": "object", "required": ["path", "target"], "properties": { "path": { "type": "string", "minLength": 1 }, "target": { "type": "string", "minLength": 1 }, "public": { "type": "boolean", "default": false } }, "additionalProperties": false }, "default": [] }, "public_paths": { "type": "array", "items": { "type": "string" }, "default": [] }, "container_registrars": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "FQCN of a ContainerRegistrar." }, "default": [] }, "ui_slots": { "description": "Keyed by slot name (e.g. 'aside.tab_panel'). Values are arrays of contribution objects.", "anyOf": [ { "type": "object", "patternProperties": { "^.+$": { "type": "array", "items": { "type": "object", "required": ["key"], "properties": { "key": { "type": "string", "minLength": 1 }, "label": { "type": "string" }, "icon": { "type": "string" }, "href": { "type": "string" }, "permission": { "type": "string" }, "panel_template": { "type": "string" }, "template": { "type": "string" }, "path": { "type": "string" }, "script": { "type": "string" }, "export": { "type": "string" }, "selector": { "type": "string" }, "scope": { "type": "string" }, "config_path": { "type": "string" }, "default_config": { "anyOf": [ { "type": "object" }, { "type": "array", "maxItems": 0 } ] }, "phase": { "type": "string", "enum": ["early", "default", "late"] }, "type": { "type": "string" }, "order": { "type": "integer", "default": 100 }, "details_storage": { "type": "string" }, "details_open_active": { "type": "boolean" }, "base_url": { "type": "string" }, "group": { "type": "string", "description": "Sidebar nav group key for grouping related items under a details/summary section." } } } } } }, { "type": "array", "maxItems": 0 } ], "default": {} }, "search_resources": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "FQCN of a SearchResourceProvider." }, "default": [] }, "asset_groups": { "description": "Asset group name → file list.", "anyOf": [ { "type": "object", "patternProperties": { "^.+$": { "type": "array", "items": { "type": "string" } } } }, { "type": "array", "maxItems": 0 } ], "default": {} }, "layout_context_providers": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "FQCN of a LayoutContextProvider." }, "default": [] }, "session_providers": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "FQCN of a SessionProvider." }, "default": [] }, "authorization_policies": { "type": "array", "items": { "type": "string", "minLength": 1, "description": "FQCN of an AuthorizationPolicyInterface." }, "default": [] }, "permissions": { "type": "array", "items": { "type": "object", "required": ["key", "description"], "properties": { "key": { "type": "string", "minLength": 1 }, "description": { "type": "string", "minLength": 1 }, "active": { "type": ["boolean", "integer"], "default": true }, "is_system": { "type": ["boolean", "integer"], "default": true } }, "additionalProperties": false }, "default": [] }, "scheduler_jobs": { "type": "array", "items": { "type": "object", "required": [ "job_key", "handler", "label", "description", "default_enabled", "default_timezone", "default_schedule_type", "default_schedule_interval", "default_schedule_time", "default_schedule_weekdays_csv", "default_catchup_once", "allowed_schedule_types" ], "properties": { "job_key": { "type": "string", "minLength": 1 }, "handler": { "type": "string", "minLength": 1 }, "label": { "type": "string", "minLength": 1 }, "description": { "type": "string", "minLength": 1 }, "default_enabled": { "type": ["boolean", "integer"] }, "default_timezone": { "type": "string", "minLength": 1 }, "default_schedule_type": { "type": "string", "enum": ["hourly", "daily", "weekly"] }, "default_schedule_interval": { "type": "integer" }, "default_schedule_time": { "type": ["string", "null"] }, "default_schedule_weekdays_csv": { "type": ["string", "null"] }, "default_catchup_once": { "type": ["boolean", "integer"] }, "allowed_schedule_types": { "type": "array", "items": { "type": "string", "enum": ["hourly", "daily", "weekly"] }, "minItems": 1 } }, "additionalProperties": false }, "default": [] }, "event_listeners": { "description": "Event name → list of listener descriptors.", "anyOf": [ { "type": "object", "patternProperties": { "^.+$": { "type": "array", "items": { "type": "object", "required": ["class", "method"], "properties": { "class": { "type": "string", "minLength": 1, "description": "FQCN implementing EventListener." }, "method": { "type": "string", "minLength": 1 } }, "additionalProperties": false } } } }, { "type": "array", "maxItems": 0 } ], "default": {} }, "deactivation_handler": { "type": ["string", "null"], "description": "FQCN of a ModuleDeactivationHandler. Null if no cleanup needed.", "default": null }, "migrations_path": { "type": ["string", "null"], "description": "Relative path to SQL migration scripts. Resolved against module basePath.", "default": null }, "i18n_path": { "type": ["string", "null"], "description": "Relative path to i18n translation files. Resolved against module basePath.", "default": null } }, "additionalProperties": false }