Reuse an existing category's spelling in the categorizer; document the Interests page (step 9)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K9PrjtUS16PAQve8D4bHgc
This commit is contained in:
2026-09-13 05:45:53 +00:00
co-authored by Claude Fable 5.1
parent 055b1df769
commit af70da1493
2 changed files with 17 additions and 7 deletions
+12 -6
View File
@@ -354,8 +354,8 @@ async fn categorize_with_llm(db: &Db, pending: &[Interest], llm: &LlmClient) ->
.collect::<HashMap<_, _>>();
let existing_categories = categories
.iter()
.map(|category| category.to_lowercase())
.collect::<BTreeSet<_>>();
.map(|category| (category.to_lowercase(), *category))
.collect::<HashMap<_, _>>();
let mut assigned = BTreeSet::new();
let mut new_categories = BTreeSet::new();
let now = Timestamp::now();
@@ -367,10 +367,16 @@ async fn categorize_with_llm(db: &Db, pending: &[Interest], llm: &LlmClient) ->
if !(1..=60).contains(&category.chars().count()) || !assigned.insert(interest.id) {
continue;
}
// A model that answers "software" for an existing "Software" must not
// split the category.
let category = match existing_categories.get(&category.to_lowercase()) {
Some(existing) => existing,
None => {
new_categories.insert(category.to_string());
category
}
};
set_category(db, interest.id, Some(category), now).await?;
if !existing_categories.contains(&category.to_lowercase()) {
new_categories.insert(category.to_string());
}
}
let mut message = format!(
@@ -750,7 +756,7 @@ mod tests {
let backend = Arc::new(MockBackend::new());
backend.push(
r#"{"assignments":[
{"interest":"RUST MACROS","category":" Software "},
{"interest":"RUST MACROS","category":" software "},
{"interest":"Wheel-thrown pottery","category":"Creative crafts"},
{"interest":"Not in the batch","category":"Made up"}
]}"#,