mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Add mark as new API endpoint for notifications
POST /api/notifications/{id}/mark_as_new sets is_new=1, allowing a notification to be flagged as unread after it has been read.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
913bf0e839
commit
8153a216b9
@@ -93,6 +93,21 @@ pub fn mark_as_old(id: i64) -> Result<(), DbError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mark_as_new(id: i64) -> Result<(), DbError> {
|
||||||
|
let conn = db::get_db_connection();
|
||||||
|
|
||||||
|
match conn.execute("UPDATE notifications SET is_new=1 WHERE id=?1", params![id]) {
|
||||||
|
Ok(_) => {
|
||||||
|
debug!("Notification id={} flagged as new", id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
error!("Error marking notification ({id}) as new: {error}");
|
||||||
|
Err(DbError::from(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read(id: i64) -> Option<Notification> {
|
pub fn read(id: i64) -> Option<Notification> {
|
||||||
let conn = db::get_db_connection();
|
let conn = db::get_db_connection();
|
||||||
|
|
||||||
@@ -162,6 +177,36 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_mark_as_new() {
|
||||||
|
tests_common::setup().await;
|
||||||
|
|
||||||
|
// Mark non-existant notification (should be fine)
|
||||||
|
mark_as_new(9999999).unwrap();
|
||||||
|
|
||||||
|
// Create notification with is_new=false
|
||||||
|
let created_on = Utc::now();
|
||||||
|
let inserted_id = insert(Notification::new(
|
||||||
|
created_on,
|
||||||
|
NotificationType::DeviceOnlineAfterTime,
|
||||||
|
"New notification title".to_string(),
|
||||||
|
"New notification body".to_string(),
|
||||||
|
false,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Mark it as new
|
||||||
|
mark_as_new(inserted_id).unwrap();
|
||||||
|
|
||||||
|
// Read it and validate
|
||||||
|
let notification = read(inserted_id).unwrap();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
notification.is_new,
|
||||||
|
"Notification id={inserted_id} should have is_new=1."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_insert() {
|
async fn test_insert() {
|
||||||
tests_common::setup().await;
|
tests_common::setup().await;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use axum::extract::Request;
|
|||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::middleware::Next;
|
use axum::middleware::Next;
|
||||||
use axum::response::Response;
|
use axum::response::Response;
|
||||||
use axum::routing::{delete, get, put};
|
use axum::routing::{delete, get, post, put};
|
||||||
use axum::{Router, http};
|
use axum::{Router, http};
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use tower::ServiceBuilder;
|
use tower::ServiceBuilder;
|
||||||
@@ -38,6 +38,10 @@ pub async fn serve() -> Result<(), Box<dyn Error>> {
|
|||||||
"/api/notifications/{id}/read_without_flagging",
|
"/api/notifications/{id}/read_without_flagging",
|
||||||
get(notifications::read_without_flagging),
|
get(notifications::read_without_flagging),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/api/notifications/{id}/mark_as_new",
|
||||||
|
post(notifications::mark_as_new),
|
||||||
|
)
|
||||||
.route_layer(axum::middleware::from_fn(auth))
|
.route_layer(axum::middleware::from_fn(auth))
|
||||||
.layer(ServiceBuilder::new().layer(cors_layer))
|
.layer(ServiceBuilder::new().layer(cors_layer))
|
||||||
.route(
|
.route(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use axum::{
|
|||||||
Json,
|
Json,
|
||||||
extract::{Path, Query},
|
extract::{Path, Query},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
|
response::IntoResponse,
|
||||||
};
|
};
|
||||||
use log::error;
|
use log::error;
|
||||||
|
|
||||||
@@ -31,6 +32,19 @@ pub async fn read_without_flagging(Path(id): Path<i64>) -> Result<Json<Notificat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn mark_as_new(Path(id): Path<i64>) -> impl IntoResponse {
|
||||||
|
match db::notifications::mark_as_new(id) {
|
||||||
|
Ok(_) => (StatusCode::OK, "Notification marked as new"),
|
||||||
|
Err(err) => {
|
||||||
|
error!("Error marking notification (id={id}) as new: {}", err);
|
||||||
|
(
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
"Error updating notification in the server, check your logs",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn list(
|
pub async fn list(
|
||||||
Query(params): Query<HashMap<String, String>>,
|
Query(params): Query<HashMap<String, String>>,
|
||||||
) -> Result<Json<Vec<Notification>>, StatusCode> {
|
) -> Result<Json<Vec<Notification>>, StatusCode> {
|
||||||
|
|||||||
Reference in New Issue
Block a user