Compute dashboard stats
Some checks failed
Rust / Test (push) Has been cancelled
Rust / Rustfmt (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Code coverage (push) Has been cancelled

Track open rate for new post notifications (user clicked the button in
the link or not). No data about the user is collected during the
process, it only uses an ID inserted by the issue delivery worker.
This commit is contained in:
Alphonse Paix
2025-09-24 04:30:27 +02:00
parent 33281132c6
commit 4cb1d2b6fd
19 changed files with 303 additions and 60 deletions

View File

@@ -8,7 +8,7 @@ use anyhow::Context;
use askama::Template;
use axum::{
extract::{Path, Query, State},
response::{Html, IntoResponse, Response},
response::{Html, IntoResponse, Redirect, Response},
};
use sqlx::PgPool;
use uuid::Uuid;
@@ -62,12 +62,29 @@ async fn get_posts_table_size(connection_pool: &PgPool) -> Result<i64, sqlx::Err
.map(|r| r.count.unwrap())
}
#[derive(serde::Deserialize)]
pub struct PostParams {
origin: Option<Uuid>,
}
pub async fn see_post(
State(AppState {
connection_pool, ..
}): State<AppState>,
Path(post_id): Path<Uuid>,
Query(PostParams { origin }): Query<PostParams>,
) -> Result<Response, AppError> {
if let Some(origin) = origin {
sqlx::query!(
"UPDATE notifications_delivered SET opened = TRUE WHERE email_id = $1",
origin,
)
.execute(&connection_pool)
.await
.context("Failed to mark email as opened.")
.map_err(AppError::unexpected_page)?;
return Ok(Redirect::to(&format!("/posts/{}", post_id)).into_response());
}
let post = get_post_data(&connection_pool, post_id)
.await
.context(format!("Failed to fetch post #{}", post_id))