mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-17 04:06:44 +02:00
- Serveur Rust (server-rs/, axum + sqlx) : les 148 adresses de l'API, l'interface, les migrations de démarrage et les tâches de fond ; même comportement que Node (banc : 2027 cas, 0 écart hors écarts déclarés USERS-02, RAPPRO-21, R4, R5). - Node retiré : server/, dépendances serveur, image Docker sans Node (51 Mo), docker-compose à un seul service applicatif. - R4 : écritures d'un autre site refusées (Sec-Fetch-Site / Origin). - R5 : « aujourd'hui » et sauvegarde automatique à l'heure de Paris. - R6 : mainteneur dans .github/CODEOWNERS. - Menu latéral : Accueil puis Calendrier en tête. - Plan et état : docs/PLAN-MIGRATION-RUST.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ke2qyS8rgacP3ap5iezDbM
98 lines
2.6 KiB
Rust
98 lines
2.6 KiB
Rust
// Serveur LogiFlow : l'API (router.rs), l'interface construite par Vite
|
|
// (static_files.rs), les migrations de démarrage et les tâches de fond.
|
|
// Il a remplacé le serveur Node (docs/PLAN-MIGRATION-RUST.md).
|
|
|
|
mod access;
|
|
mod auth;
|
|
mod clock;
|
|
mod config;
|
|
mod crypto;
|
|
mod db;
|
|
mod error;
|
|
mod express_routes;
|
|
mod http;
|
|
mod jobs;
|
|
mod js;
|
|
mod json;
|
|
mod modules;
|
|
mod origin;
|
|
mod projections;
|
|
mod request;
|
|
mod router;
|
|
mod schema;
|
|
mod services;
|
|
mod startup;
|
|
mod static_files;
|
|
mod zod;
|
|
|
|
use std::net::SocketAddr;
|
|
use std::sync::Arc;
|
|
use std::time::Duration;
|
|
|
|
use sqlx::postgres::PgPoolOptions;
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
use crate::config::Config;
|
|
|
|
#[derive(Clone)]
|
|
pub struct AppState {
|
|
pub config: Arc<Config>,
|
|
pub db: sqlx::PgPool,
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
tracing_subscriber::fmt()
|
|
// Pas de couleurs dans les journaux Docker
|
|
.with_ansi(std::io::IsTerminal::is_terminal(&std::io::stdout()))
|
|
.with_env_filter(
|
|
EnvFilter::try_from_env("RUST_LOG").unwrap_or_else(|_| EnvFilter::new("info,sqlx=warn")),
|
|
)
|
|
.init();
|
|
|
|
let config = Config::from_env()?;
|
|
// Connexion paresseuse : le serveur démarre même si la base n'est pas encore prête
|
|
let db = PgPoolOptions::new()
|
|
.max_connections(20)
|
|
.acquire_timeout(Duration::from_secs(15))
|
|
.idle_timeout(Duration::from_secs(30))
|
|
.connect_lazy(&config.database_url)?;
|
|
|
|
// Comme Node : migrations avant d'accepter des requêtes, puis compte admin,
|
|
// index en arrière-plan et tâches de fond
|
|
startup::run_migrations(&db, &config.encryption_key).await;
|
|
jobs::ensure_default_admin(&db).await;
|
|
startup::spawn_performance_indexes(db.clone());
|
|
|
|
let state = AppState {
|
|
config: Arc::new(config),
|
|
db,
|
|
};
|
|
let port = state.config.port;
|
|
tracing::info!(port, "LogiFlow démarre");
|
|
|
|
jobs::spawn(state.clone());
|
|
let app = router::build(state);
|
|
let listener = tokio::net::TcpListener::bind(SocketAddr::from(([0, 0, 0, 0], port))).await?;
|
|
axum::serve(listener, app.into_make_service_with_connect_info::<SocketAddr>())
|
|
.with_graceful_shutdown(shutdown_signal())
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
async fn shutdown_signal() {
|
|
let ctrl_c = async {
|
|
let _ = tokio::signal::ctrl_c().await;
|
|
};
|
|
let terminate = async {
|
|
if let Ok(mut signal) = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) {
|
|
signal.recv().await;
|
|
}
|
|
};
|
|
tokio::select! {
|
|
_ = ctrl_c => {},
|
|
_ = terminate => {},
|
|
}
|
|
tracing::info!("arrêt demandé");
|
|
}
|