Struttura del Progetto

Come Flux organizza il tuo codice per massima produttivitΓ  e chiarezza

Filosofia: Flux segue il principio "convention over configuration" - una struttura standard che funziona subito, ma completamente personalizzabile.

Panoramica della Struttura

Quando crei un nuovo progetto Flux, viene generata questa struttura:

my-app/
β”œβ”€β”€ app/                    # Cuore dell'applicazione
β”‚   β”œβ”€β”€ routes.flux        # Definizione delle route
β”‚   β”œβ”€β”€ controllers/       # Controller (logica)
β”‚   β”œβ”€β”€ models/           # Modelli database
β”‚   β”œβ”€β”€ middleware/       # Middleware personalizzati
β”‚   └── services/         # Servizi e helper
β”œβ”€β”€ views/                # Template HTML
β”‚   β”œβ”€β”€ layouts/         # Layout riutilizzabili
β”‚   β”œβ”€β”€ components/      # Componenti UI
β”‚   └── errors/          # Pagine di errore
β”œβ”€β”€ public/              # Asset pubblici
β”‚   β”œβ”€β”€ css/            # Fogli di stile
β”‚   β”œβ”€β”€ js/             # JavaScript client
β”‚   β”œβ”€β”€ images/         # Immagini
β”‚   └── uploads/        # File caricati
β”œβ”€β”€ config/             # Configurazioni
β”‚   β”œβ”€β”€ app.flux       # Config applicazione
β”‚   β”œβ”€β”€ database.flux  # Config database
β”‚   └── routes.flux    # Route avanzate
β”œβ”€β”€ storage/           # File generati
β”‚   β”œβ”€β”€ cache/        # Cache applicazione
β”‚   β”œβ”€β”€ logs/         # Log file
β”‚   └── sessions/     # Sessioni utente
β”œβ”€β”€ tests/            # Test automatici
β”‚   β”œβ”€β”€ unit/        # Test unitari
β”‚   └── integration/ # Test integrazione
β”œβ”€β”€ .env             # Variabili ambiente
β”œβ”€β”€ .gitignore       # File da ignorare
β”œβ”€β”€ flux.json        # Configurazione progetto
└── README.md        # Documentazione progetto

Directory Principali

πŸ“ app/

Il cuore della tua applicazione. Contiene tutta la logica di business.

routes.flux

Il file principale dove definisci tutte le route della tua applicazione:

# app/routes.flux
route "/" {
    return render("home")
}

route "/api/users" requires_auth {
    return User.all().to_json()
}

route.group("/admin") requires_admin {
    route "/dashboard" uses AdminController.dashboard
    route "/users" uses AdminController.users
}

controllers/

I controller gestiscono la logica delle route complesse:

# app/controllers/UserController.flux
class UserController {
    def index(request):
        users = User.paginate(page=request.get('page', 1))
        return render("users/index", {"users": users})
    
    def create(request):
        user = User.create(request.all())
        return redirect(f"/users/{user.id}")
}

models/

I modelli rappresentano le tabelle del database:

# app/models/User.flux
model User {
    # Campi del modello
    name: string(100)
    email: string unique
    password: string hidden
    created_at: datetime auto
    
    # Relazioni
    has_many posts
    belongs_to_many roles
    
    # Metodi personalizzati
    def full_name():
        return f"{self.first_name} {self.last_name}"
}

🎨 views/

Contiene tutti i template HTML. Flux usa un sistema di template potente ma semplice:

<!-- views/layouts/app.flux.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My App{% endblock %}</title>
    <link rel="stylesheet" href="/css/app.css">
</head>
<body>
    {% include "components/navbar" %}
    
    <main>
        {% block content %}{% endblock %}
    </main>
    
    {% include "components/footer" %}
</body>
</html>

🌐 public/

Tutti i file in questa directory sono accessibili pubblicamente via web:

# Accessibili via browser:
/css/style.css     β†’ http://tuoapp.com/css/style.css
/js/app.js         β†’ http://tuoapp.com/js/app.js
/images/logo.png   β†’ http://tuoapp.com/images/logo.png

βš™οΈ config/

Configurazioni dell'applicazione, database, servizi esterni:

# config/database.flux
database {
    default = "mysql"
    
    connections {
        mysql {
            host = env("DB_HOST", "localhost")
            port = env("DB_PORT", 3306)
            database = env("DB_NAME", "flux_app")
            username = env("DB_USER", "root")
            password = env("DB_PASSWORD", "")
        }
        
        redis {
            host = env("REDIS_HOST", "localhost")
            port = env("REDIS_PORT", 6379)
        }
    }
}

File Importanti

flux.json

Il file di configurazione principale del progetto:

{
    "name": "my-awesome-app",
    "version": "1.0.0",
    "description": "La mia app Flux",
    "author": "Nome Cognome",
    "license": "MIT",
    "dependencies": {
        "flux-auth": "^1.0.0",
        "flux-mail": "^1.0.0"
    },
    "scripts": {
        "dev": "flux serve",
        "build": "flux build",
        "test": "flux test"
    }
}

.env

Variabili d'ambiente per configurazioni sensibili:

# NON committare questo file!
APP_ENV=development
APP_DEBUG=true
APP_KEY=tua-chiave-segreta-unica

DB_HOST=localhost
DB_PORT=3306
DB_NAME=my_app
DB_USER=root
DB_PASSWORD=password

MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null

Best Practices

πŸ—‚ Organizzazione

  • Mantieni i controller snelli, sposta la logica nei services
  • Un model per file nella directory models/
  • Raggruppa i template per funzionalitΓ  in sottocartelle

πŸ”’ Sicurezza

  • Mai committare il file .env
  • Usa sempre variabili d'ambiente per dati sensibili
  • La cartella storage/ non deve essere pubblica

πŸš€ Performance

  • Minimizza CSS/JS in produzione
  • Usa la cache per query costose
  • Ottimizza le immagini in public/images

Strutture Personalizzate

Flux Γ¨ flessibile. Puoi aggiungere le tue directory:

my-app/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ ...
β”‚   β”œβ”€β”€ events/          # Eventi applicazione
β”‚   β”œβ”€β”€ jobs/           # Job asincroni
β”‚   β”œβ”€β”€ mail/           # Template email
β”‚   └── validators/     # Validatori custom
β”œβ”€β”€ resources/          # Risorse non compilate
β”‚   β”œβ”€β”€ sass/          # File SASS
β”‚   └── js/            # JavaScript ES6+
└── ...

Esempio Pratico

Vediamo come i file lavorano insieme in un blog:

# app/routes.flux
route "/blog" uses BlogController.index
route "/blog/:slug" uses BlogController.show
route "/blog/create" requires_auth uses BlogController.create
route "/blog/:id/edit" requires_auth uses BlogController.edit
# app/controllers/BlogController.flux
class BlogController {
    def index(request):
        posts = Post.published().paginate(10)
        return render("blog/index", {"posts": posts})
    
    def show(request, slug):
        post = Post.where(slug=slug).first_or_404()
        return render("blog/show", {"post": post})
}
# app/models/Post.flux
model Post {
    title: string(200)
    slug: string unique
    content: text
    published_at: datetime nullable
    
    belongs_to user
    has_many comments
    
    scope published():
        return self.where_not_null('published_at')
    
    def excerpt(length=150):
        return self.content[:length] + "..."
}
<!-- views/blog/index.flux.html -->
{% extends "layouts/app" %}

{% block content %}
    <h1>Blog</h1>
    
    {% for post in posts %}
        <article>
            <h2>
                <a href="/blog/{{ post.slug }}">
                    {{ post.title }}
                </a>
            </h2>
            <p>{{ post.excerpt() }}</p>
            <small>{{ post.published_at.format('%d/%m/%Y') }}</small>
        </article>
    {% endfor %}
    
    {{ posts.links() }}
{% endblock %}
πŸ’‘ Suggerimento: Usa flux generate per creare automaticamente file con la struttura corretta: flux generate controller BlogController