refactor (v2): better arch
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
48
crates/application/src/smart/process_note.rs
Normal file
48
crates/application/src/smart/process_note.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use domain::{
|
||||
errors::DomainResult,
|
||||
note::entity::{NoteId, NoteLink},
|
||||
user::entity::UserId,
|
||||
};
|
||||
|
||||
use crate::context::AppContext;
|
||||
|
||||
pub async fn execute(ctx: &AppContext, note_id: NoteId, _user_id: UserId) -> DomainResult<()> {
|
||||
let (Some(embedder), Some(vector_store)) = (
|
||||
ctx.services.embedding.as_ref(),
|
||||
ctx.services.vector_store.as_ref(),
|
||||
) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let note = ctx.repos.note.find_by_id(¬e_id).await?;
|
||||
let Some(note) = note else { return Ok(()) };
|
||||
|
||||
let text = match ¬e.title {
|
||||
Some(t) => format!("{} {}", t.as_ref(), note.content),
|
||||
None => note.content.clone(),
|
||||
};
|
||||
|
||||
let embedding = embedder.generate(&text).await?;
|
||||
vector_store.upsert(¬e_id, &embedding).await?;
|
||||
|
||||
let limit = ctx.config.smart.neighbour_limit;
|
||||
let similar = vector_store.find_similar(&embedding, limit + 1).await?;
|
||||
|
||||
let links: Vec<NoteLink> = similar
|
||||
.into_iter()
|
||||
.filter(|(id, score)| *id != note_id && *score >= ctx.config.smart.min_similarity)
|
||||
.take(limit)
|
||||
.map(|(target_id, score)| NoteLink::new(note_id, target_id, score))
|
||||
.collect();
|
||||
|
||||
ctx.repos.link.delete_for_source(¬e_id).await?;
|
||||
if !links.is_empty() {
|
||||
ctx.repos.link.save_links(&links).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "tests/process_note.rs"]
|
||||
mod tests;
|
||||
Reference in New Issue
Block a user