clean project structure
ci/woodpecker/push/tests Pipeline was canceled

This commit is contained in:
qpismont committed 2026-10-13 19:57:24 +00:00
1 parent 7493de6952
commit 3078ba5705
45 files changed
+2139 -1880

No files matched your search

+15 -9
View File
@@ -28,8 +28,8 @@ pub async fn start(app_state: AppState) -> anyhow::Result<()> {
let http_port = app_state.config.http_port;
let shutdown = app_state.shutdown.clone();
// Le dashboard est servi depuis un dossier statique ; les routes API
// ci-dessous restent prioritaires (le dossier n'est que le fallback).
// The dashboard is served from a static directory; the API routes below take
// precedence (the directory is only the fallback).
let front_dir = std::env::var("FRONT_DIR").unwrap_or_else(|_| String::from("front"));
if !std::path::Path::new(&front_dir).is_dir() {
warn!(dir = %front_dir, "front directory not found, the dashboard will 404");
@@ -38,7 +38,7 @@ pub async fn start(app_state: AppState) -> anyhow::Result<()> {
let app = Router::new()
.route("/webhook", post(webhook))
.route("/dedup", get(dedup_list))
.route("/reviews", get(reviews_list))
.route("/jobs", get(jobs_list))
.route("/events", get(lifecycle_events))
.route("/jobs/{id}/events", get(job_events))
@@ -63,8 +63,8 @@ pub async fn start(app_state: AppState) -> anyhow::Result<()> {
Ok(())
}
async fn dedup_list(State(app_state): State<AppState>) -> Result<impl IntoResponse, AppError> {
let reviews = app_state.dedup.list_reviews().await?;
async fn reviews_list(State(app_state): State<AppState>) -> Result<impl IntoResponse, AppError> {
let reviews = app_state.reviews.list().await?;
Ok(Json(json!({
"reviews": reviews
@@ -81,10 +81,10 @@ async fn jobs_list(State(app_state): State<AppState>) -> Result<impl IntoRespons
})))
}
/// Flux SSE des évènements de cycle de vie global (liste des jobs).
/// SSE stream of the global lifecycle events (the job list).
///
/// Le flux est clos dès que l'arrêt gracieux est lancé, sans quoi une connexion
/// SSE vivante empêcherait le serveur de s'arrêter.
/// The stream is closed as soon as the graceful shutdown starts: a live SSE
/// connection would otherwise keep the server from stopping.
async fn lifecycle_events(
State(app_state): State<AppState>,
) -> Sse<impl Stream<Item = Result<Event, axum::Error>>> {
@@ -143,7 +143,7 @@ async fn webhook(
metrics::webhook_received(event_type);
let event_id = wb.event_id();
match app_state.dedup.is_known(event_id).await {
match is_known(&app_state, event_id).await {
Ok(true) => {
metrics::webhook_duplicate(event_type);
return Err(AppError::AlreadyProcessedErr);
@@ -172,6 +172,12 @@ async fn webhook(
Ok((StatusCode::CREATED, "Task started"))
}
/// Whether an event is already queued, or already reviewed.
async fn is_known(app_state: &AppState, event_id: u64) -> toasty::Result<bool> {
Ok(app_state.queue.is_queued(event_id).await?
|| app_state.reviews.is_reviewed(event_id).await?)
}
pub struct WebhookExtract(pub WebhookType);
impl<S> FromRequest<S> for WebhookExtract