mirror of
https://git.dirksys.ovh/dirk/bankserver.git
synced 2025-12-20 02:59:20 +01:00
support marking chat messages as read
This commit is contained in:
parent
a6cdd5377b
commit
ec40de6068
@ -12,6 +12,7 @@ use crate::{
|
||||
pub struct Chat {
|
||||
pub id: Uuid,
|
||||
pub created: DateTime<Utc>,
|
||||
pub read_until: Option<Uuid>,
|
||||
}
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "schemas", derive(schemars::JsonSchema))]
|
||||
|
||||
@ -537,6 +537,38 @@ paths:
|
||||
$ref: '#/components/responses/InvalidBody'
|
||||
default:
|
||||
$ref: '#/components/responses/Default'
|
||||
/api/chats/{chatId}/messages/{messageId}/read:
|
||||
post:
|
||||
operationId: mark-chat-message-read
|
||||
summary: Mark message as read/unread
|
||||
tags:
|
||||
- Chats
|
||||
security:
|
||||
- bearer: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/ChatId'
|
||||
- $ref: '#/components/parameters/MessageId'
|
||||
responses:
|
||||
200:
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ChatMessage'
|
||||
401:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
403:
|
||||
description: Forbidden
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ApiError'
|
||||
404:
|
||||
$ref: '#/components/responses/ResourceNotFound'
|
||||
422:
|
||||
$ref: '#/components/responses/InvalidBody'
|
||||
default:
|
||||
$ref: '#/components/responses/Default'
|
||||
/api/socket:
|
||||
get:
|
||||
operationId: websocket-events
|
||||
@ -586,6 +618,13 @@ components:
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
MessageId:
|
||||
name: messageId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
PaginationLimit:
|
||||
name: limit
|
||||
in: query
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{Router, extract::Path, routing::get};
|
||||
use axum::{
|
||||
Router,
|
||||
extract::Path,
|
||||
routing::{get, post},
|
||||
};
|
||||
use bank_core::{
|
||||
ApiError,
|
||||
chat::{Chat, ChatInfo, ChatMessage, SendMessage, StartChat},
|
||||
@ -23,6 +27,7 @@ pub(super) fn router() -> Router<Arc<AppState>> {
|
||||
.route("/", get(list_chats).post(create_chat))
|
||||
.route("/{id}", get(get_chat))
|
||||
.route("/{id}/messages", get(get_messages).post(send_message))
|
||||
.route("/{id}/messages/{messageId}/read", post(mark_read))
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
@ -108,3 +113,14 @@ pub async fn send_message(
|
||||
}
|
||||
Ok(Json(message))
|
||||
}
|
||||
|
||||
pub async fn mark_read(
|
||||
EState(state): State,
|
||||
auth: Auth,
|
||||
Path((chat_id, message_id)): Path<(Uuid, Uuid)>,
|
||||
) -> Result<(), Error> {
|
||||
let mut client = state.conn().await?;
|
||||
check_chat(&client, chat_id, auth.user_id()).await?;
|
||||
Chats::mark_read(&mut client, auth.user_id(), chat_id, message_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ fn chat_from_row(row: Row) -> Chat {
|
||||
Chat {
|
||||
id: row.get("id"),
|
||||
created: row.get("created"),
|
||||
read_until: row.get("read_until"),
|
||||
}
|
||||
}
|
||||
fn chat_info_from_row(row: Row) -> ChatInfo {
|
||||
@ -138,6 +139,7 @@ impl Chats {
|
||||
Ok(Chat {
|
||||
id,
|
||||
created: result.get(0),
|
||||
read_until: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -147,7 +149,7 @@ impl Chats {
|
||||
user: Uuid,
|
||||
pagination: RequestPagination,
|
||||
) -> Result<Pagination<Chat>, tokio_postgres::Error> {
|
||||
let stmt = client.prepare_cached("select c.id as id, c.created as created from chat_members cm join chats c on cm.chat = c.id where cm.\"user\" = $1 order by c.created desc limit $2 offset $3").await?;
|
||||
let stmt = client.prepare_cached("select c.*, cmru.read_until, array_agg(cm.\"user\") as members from chats c join chat_members cm on cm.chat = c.id join chat_members cmru on cmru.chat = c.id and cmru.\"user\" = $1 where cm.\"user\" = $1 group by c.id, cmru.read_until order by c.created desc limit $2 offset $3").await?;
|
||||
let count_stmt = client.prepare_cached("select count(c.id) from chat_members cm join chats c on cm.chat = c.id where cm.\"user\" = $1").await?;
|
||||
let result = client
|
||||
.query(&stmt, &[&user, &pagination.limit(), &pagination.offset()])
|
||||
@ -207,4 +209,19 @@ impl Chats {
|
||||
extra,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn mark_read(
|
||||
client: &mut impl GenericClient,
|
||||
user: Uuid,
|
||||
chat: Uuid,
|
||||
message: Uuid,
|
||||
) -> Result<bool, tokio_postgres::Error> {
|
||||
let stmt = client
|
||||
.prepare_cached(
|
||||
"update chat_members set read_until = $3 where chat = $1 and \"user\" = $2",
|
||||
)
|
||||
.await?;
|
||||
let rows = client.execute(&stmt, &[&chat, &user, &message]).await?;
|
||||
Ok(rows == 1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,6 +119,54 @@ jsonpath "$.extra" == null
|
||||
[Captures]
|
||||
message2: jsonpath "$.id"
|
||||
|
||||
## Test read status
|
||||
|
||||
GET {{host}}/api/chats/{{chat}}
|
||||
Authorization: Bearer {{user1-token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" == {{chat}}
|
||||
jsonpath "$.read_until" == null
|
||||
|
||||
GET {{host}}/api/chats/{{chat}}
|
||||
Authorization: Bearer {{user2-token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" == {{chat}}
|
||||
jsonpath "$.read_until" == null
|
||||
|
||||
|
||||
POST {{host}}/api/chats/{{chat}}/messages/{{message2}}/read
|
||||
Authorization: Bearer {{user2-token}}
|
||||
HTTP 200
|
||||
|
||||
GET {{host}}/api/chats/{{chat}}
|
||||
Authorization: Bearer {{user2-token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" == {{chat}}
|
||||
jsonpath "$.read_until" == {{message2}}
|
||||
|
||||
|
||||
POST {{host}}/api/chats/{{chat}}/messages/{{message1}}/read
|
||||
Authorization: Bearer {{user2-token}}
|
||||
HTTP 200
|
||||
|
||||
GET {{host}}/api/chats/{{chat}}
|
||||
Authorization: Bearer {{user2-token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" == {{chat}}
|
||||
jsonpath "$.read_until" == {{message1}}
|
||||
|
||||
|
||||
GET {{host}}/api/chats/{{chat}}
|
||||
Authorization: Bearer {{user1-token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.id" == {{chat}}
|
||||
jsonpath "$.read_until" == null
|
||||
|
||||
# Verify list messages endpoint
|
||||
|
||||
GET {{host}}/api/chats/{{chat}}/messages?limit=50
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user