fix in db and collaborate

This commit is contained in:
Mateusz Gruszczyński
2026-08-04 14:22:26 +02:00
parent 1a77ccd1bf
commit 8d58549d11
26 changed files with 3009 additions and 298 deletions
+68 -21
View File
@@ -30,6 +30,7 @@ use sha2::{Digest, Sha256};
use slug::slugify;
use crate::{
collab::{self, AppliedOperation},
db, queries,
state::{NoteUpdate, RoomEvent, SharedState},
};
@@ -301,10 +302,17 @@ pub struct ListPaginationMeta {
total_pages: usize,
}
fn default_list_page() -> usize { 1 }
fn default_list_per_page() -> usize { 25 }
fn default_list_page() -> usize {
1
}
fn default_list_per_page() -> usize {
25
}
fn normalize_list_per_page(value: usize) -> usize {
match value { 25 | 50 | 100 => value, _ => 25 }
match value {
25 | 50 | 100 => value,
_ => 25,
}
}
#[derive(Debug, Serialize)]
@@ -614,7 +622,12 @@ pub async fn open_workspace(
search.is_empty()
|| note.title.to_lowercase().contains(&search)
|| note.slug.to_lowercase().contains(&search)
|| note.created_by.as_deref().unwrap_or_default().to_lowercase().contains(&search)
|| note
.created_by
.as_deref()
.unwrap_or_default()
.to_lowercase()
.contains(&search)
})
.map(|note| {
let stats = stats.get(&note.id);
@@ -658,7 +671,12 @@ pub async fn open_workspace(
Ok(Json(WorkspaceOpenResponse {
workspace: workspace_info_from(&workspace, access_level),
notes,
pagination: ListPaginationMeta { page, per_page, total, total_pages },
pagination: ListPaginationMeta {
page,
per_page,
total,
total_pages,
},
}))
}
@@ -1053,26 +1071,62 @@ pub async fn restore(
.fetch_optional(state.db.pool())
.await?;
let content = content.ok_or_else(ApiError::not_found_revision)?;
let room_key = crate::state::AppState::note_room_key(&workspace_slug, &note_slug);
let channel = state.note_channel(&workspace_slug, &note_slug).await;
let collaboration_snapshot = db::note_collaboration_snapshot(&state.db, note.id).await?;
let collaborative_document = state
.collaborative_document(
&room_key,
collaboration_snapshot.content,
collaboration_snapshot.owner_map,
collaboration_snapshot.revision_id,
)
.await;
let mut document = collaborative_document.lock().await;
let base_revision_id = document.revision_id;
let operation =
collab::replace_operation(document.content.encode_utf16().count(), content, Vec::new());
let (content, owner_map) = collab::apply_operation_to_document(
&document.content,
&document.owner_map,
&operation,
&[],
)
.map_err(|_| ApiError::bad_request("The selected revision could not be restored"))?;
let (revision_id, updated_at) = db::save_revision(
&state.db,
note.id,
workspace.id,
&content,
Some("restore"),
"[]",
&owner_map,
)
.await?;
let update_id = u64::try_from(revision_id).unwrap_or_default().max(1);
let applied = AppliedOperation {
base_revision_id,
revision_id,
client_id: "server_restore".into(),
update_id,
operation: operation.clone(),
owner_replacements: Vec::new(),
};
document.content.clone_from(&content);
document.owner_map.clone_from(&owner_map);
document.revision_id = revision_id;
document.record(applied);
let update = NoteUpdate {
content,
base_revision_id,
revision_id,
updated_at,
author: Some("restore".into()),
owner_map: "[]".into(),
client_id: "server_restore".into(),
update_id,
operation,
owner_replacements: Vec::new(),
};
let _ = state
.note_channel(&workspace_slug, &note_slug)
.await
.send(RoomEvent::Document(update));
let _ = channel.send(RoomEvent::Document(update));
drop(document);
Ok(Json(serde_json::json!({"ok": true})))
}
@@ -1217,15 +1271,8 @@ async fn effective_header_access_level(
is_private: i64,
password_protected: bool,
) -> Result<AccessLevel, ApiError> {
let mut level = request_access_level(
state,
headers,
kind,
slug,
None,
bearer_token(headers),
)
.await?;
let mut level =
request_access_level(state, headers, kind, slug, None, bearer_token(headers)).await?;
if is_private == 0 && !password_protected {
level = std::cmp::max(level, AccessLevel::Write);
}