refactor: architecture modules indépendants — nettoyage CORE, registry enrichi, page modules dynamique
- Supprimer les modules services et logs du CORE (déplacés dans viewServices et viewLogs) - Enrichir modules/module.go : interface Registry avec NavItemDef, RunOnTarget, StreamOnTarget - Réécrire modules/loader.go : NewLoader accepte *db.DB, *sshpool.Pool, *crypto.Encryptor - Ajouter migration 005 : colonnes nav_* sur la table modules + suppression services/logs DB - Mettre à jour db.go (repairSchema) pour ajout idempotent des colonnes nav_* - Mettre à jour settings.go : GetModules retourne les champs nav, ajout GetRegistryModules et InstallRegistryModule - Mettre à jour main.go : NewLoader avec les bons arguments, ajout routes /api/registry/modules - Mettre à jour modules.html : section Store avec liste des modules Forgejo - Mettre à jour app.js : sidebar dynamique (nav_href depuis DB), modulesPage avec store - Mettre à jour pages.css : styles pour store de modules Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
91cf788221
commit
ec7d120ef6
15 changed files with 460 additions and 997 deletions
|
|
@ -1,5 +1,4 @@
|
|||
// Package modules définit le contrat d'interface pour les modules ProxmoxPanel.
|
||||
// Chaque module implémente l'interface Module et s'enregistre auprès du ModuleRegistry.
|
||||
package modules
|
||||
|
||||
import (
|
||||
|
|
@ -9,36 +8,49 @@ import (
|
|||
|
||||
// Module est l'interface que chaque module doit implémenter.
|
||||
type Module interface {
|
||||
// ID retourne l'identifiant unique du module (doit correspondre à la table modules en DB).
|
||||
ID() string
|
||||
|
||||
// Register est appelé au chargement du module actif.
|
||||
// Il reçoit le registry pour enregistrer ses routes, widgets, etc.
|
||||
Register(registry Registry) error
|
||||
}
|
||||
|
||||
// NavItemDef décrit l'entrée de navigation d'un module dans la sidebar.
|
||||
type NavItemDef struct {
|
||||
ID string `json:"id"`
|
||||
Href string `json:"href"`
|
||||
Icon string `json:"icon"`
|
||||
Color string `json:"color"`
|
||||
LabelKey string `json:"label_key"`
|
||||
}
|
||||
|
||||
// Registry est l'interface exposée aux modules pour s'enregistrer dans le CORE.
|
||||
// Seuls des types de la bibliothèque standard sont exposés — aucun type internal.
|
||||
type Registry interface {
|
||||
// RegisterRoute enregistre une route HTTP dans le router principal.
|
||||
// Enregistrement de routes HTTP
|
||||
RegisterRoute(method, path string, handler http.HandlerFunc, requireAdmin bool)
|
||||
|
||||
// RegisterWSChannel enregistre un handler WebSocket pour un channel nommé.
|
||||
// Enregistrement du canal WebSocket
|
||||
RegisterWSChannel(channel string, handler WSHandler)
|
||||
|
||||
// RegisterWidget déclare un type de widget disponible pour le dashboard.
|
||||
// Widgets et onglets
|
||||
RegisterWidget(widget WidgetDef)
|
||||
|
||||
// RegisterSettingsTab ajoute un onglet dans la page paramètres.
|
||||
RegisterSettingsTab(tab SettingsTabDef)
|
||||
|
||||
// RegisterTranslations fusionne des clés de traduction pour une langue donnée.
|
||||
// Traductions et migrations
|
||||
RegisterTranslations(lang string, keys map[string]string)
|
||||
|
||||
// RegisterMigration déclare une migration de base de données propre au module.
|
||||
RegisterMigration(version int, sql string, fn MigrationFn)
|
||||
|
||||
// DB retourne un accès à SQLite avec isolation par module (préfixe de tables).
|
||||
// Entrée de navigation dans la sidebar
|
||||
RegisterNavItem(item NavItemDef)
|
||||
|
||||
// Accès à la base SQLite (isolation par module possible via préfixe)
|
||||
DB() *sql.DB
|
||||
|
||||
// Service SSH — exécute une commande sur la cible (host ou lxc:VMID)
|
||||
// La cible "host" exécute directement, "lxc:101" wrappe via pct exec
|
||||
RunOnTarget(target, command string) (string, error)
|
||||
|
||||
// Service SSH — streaming de la sortie ligne par ligne
|
||||
// Le channel est fermé à la fin de la commande
|
||||
StreamOnTarget(target, command string, output chan<- string) error
|
||||
}
|
||||
|
||||
// WSHandler est un handler WebSocket pour un channel nommé.
|
||||
|
|
@ -55,12 +67,11 @@ type WidgetDef struct {
|
|||
|
||||
// SettingsTabDef décrit un onglet de paramètres fourni par un module.
|
||||
type SettingsTabDef struct {
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Icon string `json:"icon"`
|
||||
// Path est le chemin frontend du composant Vue à charger (lazy import).
|
||||
ID string `json:"id"`
|
||||
Label string `json:"label"`
|
||||
Icon string `json:"icon"`
|
||||
ComponentPath string `json:"component_path"`
|
||||
}
|
||||
|
||||
// MigrationFn est une fonction de migration optionnelle (pour les migrations non-SQL).
|
||||
// MigrationFn est une fonction de migration optionnelle.
|
||||
type MigrationFn func(db *sql.DB) error
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue