feat(FN-4918): merge fusion/fn-4918

This commit is contained in:
gsxdsm
2026-05-18 16:23:06 -07:00
parent 0bf89e7813
commit 0046fc92e2
11 changed files with 564 additions and 10 deletions

View File

@@ -1,3 +1,5 @@
import { createHash } from "node:crypto";
import type { Column } from "./types.js";
export interface DuplicateMatch {
@@ -20,6 +22,11 @@ export interface DuplicateCandidate {
column: Column;
}
export interface ContentFingerprintInput {
title?: string | null;
description: string;
}
const DEFAULT_THRESHOLD = 0.45;
const DEFAULT_LIMIT = 5;
const DEFAULT_EXCLUDE_COLUMNS: Column[] = ["done", "archived"];
@@ -39,6 +46,34 @@ const STOPWORDS = new Set([
"fn",
]);
function normalizeFingerprintPart(value: string): string {
return value
.toLowerCase()
.replace(/[,.;:!?"'`(){}]+/g, "")
.replaceAll("[", "")
.replaceAll("]", "")
.replace(/$/u, "")
.replace(/\s+/g, " ")
.trim();
}
/**
* Deterministic dedup fingerprint for task content.
*/
export function computeContentFingerprint(
input: ContentFingerprintInput,
): string | null {
const normalizedDescription = normalizeFingerprintPart(input.description);
if (normalizedDescription.length === 0) {
return null;
}
const normalizedTitle = normalizeFingerprintPart(input.title ?? "");
return createHash("sha256")
.update(`${normalizedTitle}\n${normalizedDescription}`)
.digest("hex");
}
function tokenize(value: string): string[] {
return value
.toLowerCase()