diff --git a/schemas/app-template.schema.json b/schemas/app-template.schema.json new file mode 100644 index 0000000..6075108 --- /dev/null +++ b/schemas/app-template.schema.json @@ -0,0 +1,244 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://irbis-os.org/schemas/app-template.schema.json", + "title": "Irbis OS Application Template", + "description": "Schéma de définition pour les applications communautaires de l'App Store Irbis OS", + "type": "object", + "required": [ + "id", + "name", + "tagline", + "description", + "category", + "version", + "developer" + ], + "additionalProperties": false, + "properties": { + "$schema": { + "type": "string", + "description": "URI du schéma JSON utilisé pour l'auto-complétion et la validation" + }, + "id": { + "type": "string", + "pattern": "^[a-z0-9-]+$", + "minLength": 2, + "maxLength": 64, + "description": "Identifiant unique de l'application en minuscules (ex: nextcloud, homeassistant)" + }, + "name": { + "type": "string", + "minLength": 2, + "maxLength": 100, + "description": "Nom complet d'affichage de l'application" + }, + "tagline": { + "type": "string", + "minLength": 5, + "maxLength": 150, + "description": "Accroche courte résumant la fonction principale de l'application" + }, + "description": { + "type": "string", + "minLength": 10, + "maxLength": 500, + "description": "Description concise de l'application (affichée sur la carte)" + }, + "longDescription": { + "type": "string", + "minLength": 20, + "maxLength": 4000, + "description": "Description détaillée affichée dans la modale de l'App Store" + }, + "icon": { + "type": "string", + "description": "Nom du fichier d'icône/image de garde (ex: icon.png) ou URL directe" + }, + "screenshots": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Noms des fichiers de captures d'écran de démo (ex: screenshot1.png) ou URLs directes" + }, + "firstStartTip": { + "type": "string", + "description": "Astuce et guide de premier démarrage affichés après l'installation" + }, + "composeFile": { + "type": "string", + "description": "Nom du fichier Docker Compose dans le dossier de l'app (défaut: docker-compose.yml)" + }, + "nginx": { + "type": "object", + "description": "Configuration du domaine et reverse proxy Nginx automatique", + "properties": { + "recommendedSubdomain": { + "type": "string", + "description": "Sous-domaine recommandé (ex: cloud, vault, media)" + }, + "enableSsl": { + "type": "boolean", + "description": "Activer le certificat SSL Let's Encrypt / HTTPS par défaut" + }, + "mainPort": { + "type": "integer", + "description": "Port cible principal pour le reverse proxy Nginx" + } + } + }, + "category": { + "type": "string", + "enum": ["media", "cloud", "productivity", "security", "utilities", "development", "home_automation", "network"], + "description": "Catégorie de l'application dans l'App Store" + }, + "version": { + "type": "string", + "pattern": "^[a-zA-Z0-9.-]+$", + "description": "Version du paquet ou du conteneur (ex: 1.0.0, stable, 2024.9.0)" + }, + "developer": { + "type": "string", + "minLength": 2, + "maxLength": 100, + "description": "Nom de l'auteur, de l'entreprise ou du projet open source" + }, + "website": { + "type": "string", + "format": "uri", + "description": "Site web officiel ou dépôt GitHub de l'application" + }, + "rating": { + "type": "number", + "minimum": 1.0, + "maximum": 5.0, + "description": "Note moyenne indicative (entre 1.0 et 5.0)" + }, + "downloads": { + "type": "string", + "description": "Indication du volume d'utilisateurs ou téléchargements (ex: 1.2M, 500K)" + }, + "sizeMb": { + "type": "number", + "minimum": 1, + "maximum": 50000, + "description": "Taille estimée de l'image Docker en mégaoctets" + }, + "license": { + "type": "string", + "description": "Licence logicielle (ex: MIT, AGPLv3, Apache-2.0, Propriétaire)" + }, + "image": { + "type": "string", + "minLength": 3, + "maxLength": 255, + "description": "Image Docker officielle ou vérifiée (ex: nextcloud:apache, lscr.io/linuxserver/plex:latest)" + }, + "defaultPort": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Port d'écoute public principal par défaut" + }, + "ports": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["privatePort", "defaultPublicPort"], + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "Nom lisible du service réseau (ex: Web UI, API, DNS)" + }, + "privatePort": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Port interne du conteneur Docker" + }, + "defaultPublicPort": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "description": "Port hôte suggéré par défaut" + }, + "description": { + "type": "string", + "description": "Description du rôle du port (ex: Interface Web, Flux RTSP, WebSocket)" + }, + "type": { + "type": "string", + "enum": ["tcp", "udp"], + "description": "Protocole de transport réseau du port" + }, + "protocol": { + "type": "string", + "enum": ["http", "https", "tcp", "udp"], + "description": "Protocole applicatif pour la redirection Nginx" + }, + "isDefaultNginxTarget": { + "type": "boolean", + "description": "Indique si ce port est la cible principale du domaine Nginx automatique" + } + } + } + }, + "volumes": { + "type": "array", + "items": { + "type": "object", + "required": ["defaultHostPath", "containerPath", "required"], + "additionalProperties": false, + "properties": { + "defaultHostPath": { + "type": "string", + "pattern": "^/.*", + "description": "Chemin hôte recommandé pour les données persistantes (généralement sous /mnt/storage/...)" + }, + "containerPath": { + "type": "string", + "pattern": "^/.*", + "description": "Chemin absolu de destination à l'intérieur du conteneur" + }, + "description": { + "type": "string", + "description": "Explication de la destination (ex: Répertoire des photos, Base de données)" + }, + "required": { + "type": "boolean", + "description": "Indique si ce volume est indispensable au bon fonctionnement" + } + } + } + }, + "env": { + "type": "array", + "items": { + "type": "object", + "required": ["key", "defaultValue", "label", "required"], + "additionalProperties": false, + "properties": { + "key": { + "type": "string", + "pattern": "^[A-Z0-9_]+$", + "description": "Nom de la variable d'environnement (ex: TZ, DB_NAME)" + }, + "defaultValue": { + "type": "string", + "description": "Valeur par défaut ou exemple" + }, + "label": { + "type": "string", + "description": "Nom convivial affiché dans l'interface" + }, + "required": { + "type": "boolean", + "description": "Indique si la variable est obligatoire" + } + } + } + } + } +}