#!/bin/bash # 🎯 GÉNÉRATEUR DE FEATURE - VEZA # Script pour gĂ©nĂ©rer une nouvelle feature complĂšte set -e # Couleurs GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' NC='\033[0m' # Fonction pour afficher les messages log_info() { echo -e "${BLUE}â„č $1${NC}" } log_success() { echo -e "${GREEN}✅ $1${NC}" } log_warning() { echo -e "${YELLOW}⚠ $1${NC}" } # VĂ©rification des arguments if [ $# -eq 0 ]; then echo "Usage: $0 " echo "Exemple: $0 user-authentication" exit 1 fi FEATURE_NAME=$1 FEATURE_DIR="features/feature-$(date +%Y%m%d)-${FEATURE_NAME}" log_info "GĂ©nĂ©ration de la feature: $FEATURE_NAME" # CrĂ©ation de la structure de la feature mkdir -p "$FEATURE_DIR"/{backend,frontend,mobile,tests,docs} log_success "Structure de rĂ©pertoires créée" # GĂ©nĂ©ration du backend (Go) log_info "GĂ©nĂ©ration du code backend..." cat > "$FEATURE_DIR/backend/${FEATURE_NAME}_service.go" << 'GOEOF' package main import ( "context" "fmt" "time" ) // ${FEATURE_NAME^}Service gĂšre les fonctionnalitĂ©s de ${FEATURE_NAME} type ${FEATURE_NAME^}Service struct { // Ajoutez vos dĂ©pendances ici } // New${FEATURE_NAME^}Service crĂ©e une nouvelle instance du service func New${FEATURE_NAME^}Service() *${FEATURE_NAME^}Service { return &${FEATURE_NAME^}Service{} } // Exemple de mĂ©thode - remplacez par vos mĂ©thodes func (s *${FEATURE_NAME^}Service) Process${FEATURE_NAME^}(ctx context.Context, input string) (string, error) { // ImplĂ©mentation de votre logique mĂ©tier return fmt.Sprintf("Processed: %s", input), nil } // Health check pour le service func (s *${FEATURE_NAME^}Service) HealthCheck() error { // ImplĂ©mentation du health check return nil } GOEOF cat > "$FEATURE_DIR/backend/${FEATURE_NAME}_handler.go" << 'GOEOF' package main import ( "net/http" "github.com/gin-gonic/gin" ) // ${FEATURE_NAME^}Handler gĂšre les endpoints HTTP pour ${FEATURE_NAME} type ${FEATURE_NAME^}Handler struct { service *${FEATURE_NAME^}Service } // New${FEATURE_NAME^}Handler crĂ©e un nouveau handler func New${FEATURE_NAME^}Handler(service *${FEATURE_NAME^}Service) *${FEATURE_NAME^}Handler { return &${FEATURE_NAME^}Handler{ service: service, } } // SetupRoutes configure les routes pour cette feature func (h *${FEATURE_NAME^}Handler) SetupRoutes(r *gin.RouterGroup) { r.GET("/${FEATURE_NAME}", h.Get${FEATURE_NAME^}) r.POST("/${FEATURE_NAME}", h.Create${FEATURE_NAME^}) r.PUT("/${FEATURE_NAME}/:id", h.Update${FEATURE_NAME^}) r.DELETE("/${FEATURE_NAME}/:id", h.Delete${FEATURE_NAME^}) } // Get${FEATURE_NAME^} rĂ©cupĂšre les donnĂ©es de ${FEATURE_NAME} func (h *${FEATURE_NAME^}Handler) Get${FEATURE_NAME^}(c *gin.Context) { // ImplĂ©mentation c.JSON(http.StatusOK, gin.H{"message": "Get ${FEATURE_NAME} endpoint"}) } // Create${FEATURE_NAME^} crĂ©e une nouvelle entrĂ©e func (h *${FEATURE_NAME^}Handler) Create${FEATURE_NAME^}(c *gin.Context) { // ImplĂ©mentation c.JSON(http.StatusCreated, gin.H{"message": "Create ${FEATURE_NAME} endpoint"}) } // Update${FEATURE_NAME^} met Ă  jour une entrĂ©e existante func (h *${FEATURE_NAME^}Handler) Update${FEATURE_NAME^}(c *gin.Context) { // ImplĂ©mentation c.JSON(http.StatusOK, gin.H{"message": "Update ${FEATURE_NAME} endpoint"}) } // Delete${FEATURE_NAME^} supprime une entrĂ©e func (h *${FEATURE_NAME^}Handler) Delete${FEATURE_NAME^}(c *gin.Context) { // ImplĂ©mentation c.JSON(http.StatusOK, gin.H{"message": "Delete ${FEATURE_NAME} endpoint"}) } GOEOF log_success "Code backend gĂ©nĂ©rĂ©" # GĂ©nĂ©ration du frontend (React) log_info "GĂ©nĂ©ration du code frontend..." cat > "$FEATURE_DIR/frontend/${FEATURE_NAME^}Page.tsx" << 'REACTEOF' import React, { useState, useEffect } from 'react'; import { Card, Button, Input, Modal } from '../components/DesignSystem'; interface ${FEATURE_NAME^}Data { id: string; name: string; // Ajoutez vos propriĂ©tĂ©s ici } const ${FEATURE_NAME^}Page: React.FC = () => { const [data, setData] = useState<${FEATURE_NAME^}Data[]>([]); const [loading, setLoading] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false); useEffect(() => { fetch${FEATURE_NAME^}Data(); }, []); const fetch${FEATURE_NAME^}Data = async () => { setLoading(true); try { // ImplĂ©mentation de la rĂ©cupĂ©ration des donnĂ©es const response = await fetch('/api/${FEATURE_NAME}'); const result = await response.json(); setData(result); } catch (error) { console.error('Erreur lors de la rĂ©cupĂ©ration des donnĂ©es:', error); } finally { setLoading(false); } }; const handleCreate = async (formData: any) => { try { // ImplĂ©mentation de la crĂ©ation const response = await fetch('/api/${FEATURE_NAME}', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData), }); if (response.ok) { fetch${FEATURE_NAME^}Data(); setIsModalOpen(false); } } catch (error) { console.error('Erreur lors de la crĂ©ation:', error); } }; return (

${FEATURE_NAME^}

{data.map((item) => (

{item.name}

{/* Ajoutez vos éléments d'affichage ici */}
))}
setIsModalOpen(false)} title="Créer ${FEATURE_NAME^}" > {/* Ajoutez votre formulaire ici */}
{ e.preventDefault(); // Implémentation de la soumission }}>
); }; export default ${FEATURE_NAME^}Page; REACTEOF log_success "Code frontend gĂ©nĂ©rĂ©" # GĂ©nĂ©ration des tests log_info "GĂ©nĂ©ration des tests..." cat > "$FEATURE_DIR/tests/${FEATURE_NAME}_test.go" << 'TESTEOF' package main import ( "testing" "context" "github.com/stretchr/testify/assert" ) func Test${FEATURE_NAME^}Service(t *testing.T) { service := New${FEATURE_NAME^}Service() t.Run("should process ${FEATURE_NAME} successfully", func(t *testing.T) { ctx := context.Background() input := "test input" result, err := service.Process${FEATURE_NAME^}(ctx, input) assert.NoError(t, err) assert.Contains(t, result, input) }) t.Run("should pass health check", func(t *testing.T) { err := service.HealthCheck() assert.NoError(t, err) }) } TESTEOF cat > "$FEATURE_DIR/tests/${FEATURE_NAME}_integration_test.go" << 'INTEGEOF' package main import ( "testing" "net/http" "net/http/httptest" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" ) func Test${FEATURE_NAME^}Endpoints(t *testing.T) { gin.SetMode(gin.TestMode) service := New${FEATURE_NAME^}Service() handler := New${FEATURE_NAME^}Handler(service) router := gin.New() handler.SetupRoutes(router.Group("/api")) t.Run("GET /api/${FEATURE_NAME}", func(t *testing.T) { w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/api/${FEATURE_NAME}", nil) router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) }) t.Run("POST /api/${FEATURE_NAME}", func(t *testing.T) { w := httptest.NewRecorder() req, _ := http.NewRequest("POST", "/api/${FEATURE_NAME}", nil) router.ServeHTTP(w, req) assert.Equal(t, http.StatusCreated, w.Code) }) } INTEGEOF log_success "Tests gĂ©nĂ©rĂ©s" # GĂ©nĂ©ration de la documentation log_info "GĂ©nĂ©ration de la documentation..." cat > "$FEATURE_DIR/docs/README.md" << 'DOCEOF' # ${FEATURE_NAME^} Feature ## Description Cette feature implĂ©mente la fonctionnalitĂ© de ${FEATURE_NAME}. ## Composants ### Backend - `${FEATURE_NAME}_service.go` - Service principal - `${FEATURE_NAME}_handler.go` - Handlers HTTP ### Frontend - `${FEATURE_NAME^}Page.tsx` - Page React ### Tests - `${FEATURE_NAME}_test.go` - Tests unitaires - `${FEATURE_NAME}_integration_test.go` - Tests d'intĂ©gration ## API Endpoints ### GET /api/${FEATURE_NAME} RĂ©cupĂšre la liste des ${FEATURE_NAME}. ### POST /api/${FEATURE_NAME} CrĂ©e une nouvelle entrĂ©e ${FEATURE_NAME}. ### PUT /api/${FEATURE_NAME}/:id Met Ă  jour une entrĂ©e ${FEATURE_NAME} existante. ### DELETE /api/${FEATURE_NAME}/:id Supprime une entrĂ©e ${FEATURE_NAME}. ## Utilisation 1. ImplĂ©mentez la logique mĂ©tier dans le service 2. Ajoutez les validations nĂ©cessaires 3. ImplĂ©mentez les tests 4. IntĂ©grez dans l'application principale ## Tests ```bash # Tests unitaires go test ./features/feature-$(date +%Y%m%d)-${FEATURE_NAME}/tests/ # Tests d'intĂ©gration go test -tags=integration ./features/feature-$(date +%Y%m%d)-${FEATURE_NAME}/tests/ ``` DOCEOF log_success "Documentation gĂ©nĂ©rĂ©e" # GĂ©nĂ©ration du fichier de configuration cat > "$FEATURE_DIR/feature-config.yaml" << 'CONFIGEOF' feature: name: ${FEATURE_NAME} version: 1.0.0 description: "Feature ${FEATURE_NAME} implementation" components: backend: service: true handler: true repository: false middleware: false frontend: page: true component: false hook: false mobile: screen: false component: false tests: unit: true integration: true e2e: false docs: readme: true api: true user_guide: false dependencies: backend: - gin - context frontend: - react - typescript mobile: - react-native - expo CONFIGEOF log_success "Configuration gĂ©nĂ©rĂ©e" # RĂ©sumĂ© echo -e "${GREEN}" echo "╔══════════════════════════════════════════════════════════════╗" echo "║ FEATURE GÉNÉRÉE AVEC SUCCÈS ║" echo "╚══════════════════════════════════════════════════════════════╝" echo -e "${NC}" echo -e "${BLUE}📁 Feature créée dans: $FEATURE_DIR${NC}" echo -e "${BLUE}📋 Prochaines Ă©tapes:${NC}" echo "1. ImplĂ©mentez la logique mĂ©tier dans les services" echo "2. Ajoutez les validations et la gestion d'erreurs" echo "3. ImplĂ©mentez les tests" echo "4. IntĂ©grez dans l'application principale" echo "5. Mettez Ă  jour la documentation" log_success "Feature $FEATURE_NAME gĂ©nĂ©rĂ©e avec succĂšs!"