Review Word change authors on existing project runs

This commit is contained in:
muena
2026-09-27 08:47:34 +02:00
parent e9cda1c02f
commit 23af4993db
4 changed files with 13 additions and 6 deletions

View File

@@ -113,6 +113,7 @@ export async function reviseProjectRun(args: {
run.origin = previous.origin;
run.revisedFrom = previous.id;
run.commentAuthorCoverage = previous.commentAuthorCoverage;
run.reviewAuthorCoverage = previous.reviewAuthorCoverage;
run.mapping = plan.mapping;
run.matchModes = Object.fromEntries(Object.entries(previous.matchModes ?? {})
.filter(([key]) => key in plan.mapping));

View File

@@ -30,6 +30,8 @@ export type ProjectRun = {
revisedFrom?: string;
/** Word comment authors were reviewed with the explicit author recognizer. */
commentAuthorCoverage?: boolean;
/** Word tracked-change authors and deleted text were reviewed. */
reviewAuthorCoverage?: boolean;
};
const DOCUMENTS = new Set([".docx", ".xlsx", ".pptx", ".pdf"]);

View File

@@ -117,9 +117,10 @@ async function prepare(root: string, files: ProjectFile[], rules: ProjectRule[],
for (const file of files) {
const data = await fs.readFile(file.absPath);
const hash = digest(data);
const recheckCommentAuthors = entityTypes.includes("PERSON") && file.kind === "document"
&& extname(file.relPath).toLowerCase() === ".docx" && !latest?.commentAuthorCoverage;
if (!recheckCommentAuthors && previousDirectory && previousOutputs.has(file.relPath)
const recheckWordReviews = entityTypes.includes("PERSON") && file.kind === "document"
&& extname(file.relPath).toLowerCase() === ".docx"
&& (!latest?.commentAuthorCoverage || !latest?.reviewAuthorCoverage);
if (!recheckWordReviews && previousDirectory && previousOutputs.has(file.relPath)
&& await matchesPreviousOutput(previousDirectory, file.relPath, hash)) {
retained.push({ file, hash });
continue;
@@ -291,6 +292,7 @@ function HitReview(props: { root: string; rules: ProjectRule[]; whitelist: Proje
run.mapping = mappingForSelection(props.preview.mapping, props.preview.previousMapping,
acceptedHits, activeMerges);
run.commentAuthorCoverage = props.preview.entityTypes.includes("PERSON");
run.reviewAuthorCoverage = props.preview.entityTypes.includes("PERSON");
run.matchModes = props.preview.matchModes;
run.sourceInPlace = props.preview.sourceInPlace || inPlace;
const usedPaths = new Set<string>();
@@ -432,7 +434,8 @@ function HitReview(props: { root: string; rules: ProjectRule[]; whitelist: Proje
tintColor: selectedGroups.has(group.key) ? Color.Green : Color.SecondaryText }}
title={group.original} subtitle={`→ ${group.placeholder}`}
accessories={[{ text: `${group.hits.length} Vorkommen` },
...(group.hits.some((hit) => hit.source === "Kommentarautor") ? [{ text: "Word-Kommentator" }] : [])]}
...(group.hits.some((hit) => hit.source === "Kommentarautor") ? [{ text: "Word-Kommentator" }] : []),
...(group.hits.some((hit) => hit.source === "Änderungsautor") ? [{ text: "Word-Bearbeiter" }] : [])]}
keywords={[type, labelForType(type)]}
actions={<ActionPanel>
<Action title={selectedGroups.has(group.key) ? "Zuordnung abwählen" : "Zuordnung auswählen"}
@@ -583,7 +586,7 @@ export default function Command() {
onChange={setRules} placeholder={"BEGRIFF: KundenSuite\nPERSON: Max Mustermann"}
info="Ein Begriff pro Zeile. Ohne Typ wird BEGRIFF verwendet. Diese Regeln werden nur für dieses Projekt gespeichert und bei der Velum-Anfrage mitgesendet." />
<Form.TagPicker id="entityTypes" title="Kategorien pseudonymisieren" value={selectedTypes}
onChange={setSelectedTypes} info="Die Auswahl wird beim Prüfen für diesen Projektordner gespeichert. Word-Kommentatoren werden nur mit der Kategorie Personen maskiert. Bei neuen Projekten sind Orte zunächst abgewählt.">
onChange={setSelectedTypes} info="Die Auswahl wird beim Prüfen für diesen Projektordner gespeichert. Word-Kommentatoren und Bearbeiter von Änderungen werden mit der Kategorie Personen maskiert. Bei neuen Projekten sind Orte zunächst abgewählt.">
{availableTypes.map((type) => <Form.TagPicker.Item key={type} value={type} title={labelForType(type)} />)}
</Form.TagPicker>
<Form.Description title="Projekt-Whitelist" text={`${whitelist.length} Begriffe werden bei diesem Ordner nicht mehr vorgeschlagen. Über die Aktionen kannst du sie wieder freigeben.`} />

View File

@@ -143,7 +143,8 @@ export async function requireProjectCapabilities(): Promise<void> {
if (!response.ok) throw new Error("Die Velum-API muss für die Projektfunktionen aktualisiert werden.");
const capabilities = await parseJsonResponse<Record<string, boolean>>(response);
if (!capabilities.request_force_masks || !capabilities.document_hit_review
|| !capabilities.document_restoration || !capabilities.comment_author_review) {
|| !capabilities.document_restoration || !capabilities.comment_author_review
|| !capabilities.revision_author_review) {
throw new Error("Die Velum-API unterstützt die Projektfunktionen noch nicht vollständig.");
}
}