From df50470e5342b72582d6ddbd57c174a9c1bb5f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20P=C3=B6ttker?= Date: Sun, 1 Nov 2026 13:35:45 +0100 Subject: [PATCH] =?UTF-8?q?fix(paperless):=20documents.checksum=20f=C3=BCr?= =?UTF-8?q?=20SHA-256=20verbreitern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Paperless-NGX ≥ 3.0 liefert original_checksum als SHA-256 (64 Zeichen). Die lokale Spiegeltabelle documents hatte nur varchar(32), wodurch die Nachbearbeitung mit „Data too long for column 'checksum'“ abbrach – nach dem Setzen von Notizen, aber vor Fertig=1. Der Task wurde dadurch jede Minute erneut verarbeitet und erzeugte doppelte Notizen. - documents.checksum auf varchar(64) (Entity + Migration) - Sync der Spiegeltabelle ist nicht mehr fatal: Fehler werden als Warnung geloggt, der Task wird trotzdem abgeschlossen Co-Authored-By: Claude Opus 5.5 --- .../src/database/entities/document.entity.ts | 3 +- .../1793600000000-DocumentChecksumSha256.ts | 28 ++++++++++ .../paperless-task-processor.service.ts | 56 +++++++++++-------- 3 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 paperless-backend/src/database/migrations/1793600000000-DocumentChecksumSha256.ts diff --git a/paperless-backend/src/database/entities/document.entity.ts b/paperless-backend/src/database/entities/document.entity.ts index 30f485a..699cf78 100644 --- a/paperless-backend/src/database/entities/document.entity.ts +++ b/paperless-backend/src/database/entities/document.entity.ts @@ -5,7 +5,8 @@ export class Document { @PrimaryColumn({ type: 'int' }) documentId!: number; - @Column({ type: 'varchar', length: 32, nullable: true }) + /** SHA-256 des Originals — Paperless ≥ 3.0 liefert 64 Zeichen (vorher MD5) */ + @Column({ type: 'varchar', length: 64, nullable: true }) checksum!: string | null; @Column({ type: 'varchar', length: 1024, nullable: true }) diff --git a/paperless-backend/src/database/migrations/1793600000000-DocumentChecksumSha256.ts b/paperless-backend/src/database/migrations/1793600000000-DocumentChecksumSha256.ts new file mode 100644 index 0000000..60c6d8d --- /dev/null +++ b/paperless-backend/src/database/migrations/1793600000000-DocumentChecksumSha256.ts @@ -0,0 +1,28 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +/** + * Paperless-NGX ≥ 3.0 liefert `original_checksum` als SHA-256 (64 Zeichen). + * Die lokale Spiegeltabelle `documents` hatte nur Platz für MD5 (32 Zeichen), + * wodurch die Nachbearbeitung neuer Dokumente mit „Data too long“ abbrach. + */ +export class DocumentChecksumSha2561793600000000 implements MigrationInterface { + name = 'DocumentChecksumSha2561793600000000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE \`documents\` + MODIFY \`checksum\` varchar(64) NULL DEFAULT NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // SHA-256-Werte passen nicht mehr in 32 Zeichen und werden verworfen. + await queryRunner.query(` + UPDATE \`documents\` SET \`checksum\` = NULL WHERE LENGTH(\`checksum\`) > 32 + `); + await queryRunner.query(` + ALTER TABLE \`documents\` + MODIFY \`checksum\` varchar(32) NULL DEFAULT NULL + `); + } +} diff --git a/paperless-backend/src/paperless/paperless-task-processor.service.ts b/paperless-backend/src/paperless/paperless-task-processor.service.ts index e96312a..1f43b72 100644 --- a/paperless-backend/src/paperless/paperless-task-processor.service.ts +++ b/paperless-backend/src/paperless/paperless-task-processor.service.ts @@ -375,34 +375,42 @@ export class PaperlessTaskProcessorService { ); } - // Sync local Documents table - this.logger.log( - `[Postprocessing] Task ${t.TaskId} - Synchronisiere lokale Documents-Tabelle`, - ); - const metadata = await this.paperlessService.getDocumentMetadata( - document.id, - ); - let localDoc = await this.documentRepo.findOne({ - where: { documentId: document.id }, - }); - - if (!localDoc) { + // Sync local Documents table — nur Spiegel; ein Fehler hier darf den Task + // nicht offen lassen, sonst würde er jede Minute erneut nachbearbeitet + // (doppelte Notizen in Paperless). + try { this.logger.log( - `[Postprocessing] Task ${t.TaskId} - Erstelle neuen lokalen Dokument-Eintrag`, + `[Postprocessing] Task ${t.TaskId} - Synchronisiere lokale Documents-Tabelle`, ); - localDoc = this.documentRepo.create({ - documentId: document.id, - checksum: metadata.original_checksum, - filename: metadata.original_filename, + const metadata = await this.paperlessService.getDocumentMetadata( + document.id, + ); + let localDoc = await this.documentRepo.findOne({ + where: { documentId: document.id }, }); - await this.documentRepo.save(localDoc); - } else { - this.logger.log( - `[Postprocessing] Task ${t.TaskId} - Aktualisiere bestehenden lokalen Dokument-Eintrag`, + + if (!localDoc) { + this.logger.log( + `[Postprocessing] Task ${t.TaskId} - Erstelle neuen lokalen Dokument-Eintrag`, + ); + localDoc = this.documentRepo.create({ + documentId: document.id, + checksum: metadata.original_checksum, + filename: metadata.original_filename, + }); + await this.documentRepo.save(localDoc); + } else { + this.logger.log( + `[Postprocessing] Task ${t.TaskId} - Aktualisiere bestehenden lokalen Dokument-Eintrag`, + ); + localDoc.checksum = metadata.original_checksum; + localDoc.filename = metadata.original_filename; + await this.documentRepo.save(localDoc); + } + } catch (syncError) { + this.logger.warn( + `[Postprocessing] Task ${t.TaskId} - Lokale Documents-Tabelle nicht synchronisiert: ${syncError.message}`, ); - localDoc.checksum = metadata.original_checksum; - localDoc.filename = metadata.original_filename; - await this.documentRepo.save(localDoc); } // Update Task status