diff --git a/ticket_form/backend/app/api/documents.py b/ticket_form/backend/app/api/documents.py index ea2a44ee..0723247f 100644 --- a/ticket_form/backend/app/api/documents.py +++ b/ticket_form/backend/app/api/documents.py @@ -614,14 +614,25 @@ async def generate_documents_list(request: Request): def compute_documents_hash(doc_ids: List[str]) -> str: - """Вычисляет hash от списка document_id для проверки актуальности черновика""" + """ + Вычисляет hash от списка document_id для проверки актуальности черновика. + Должен совпадать с JS алгоритмом в n8n build_form_draft. + """ + import ctypes + sorted_ids = sorted([d for d in doc_ids if d]) hash_input = ','.join(sorted_ids) - # Используем простой hash как в n8n (djb2) + + # djb2 hash — эмуляция JS поведения + # В JS: (hash << 5) возвращает 32-битный signed int hash_val = 5381 for char in hash_input: - hash_val = ((hash_val << 5) + hash_val) + ord(char) - return format(abs(hash_val) & 0xFFFFFFFF, 'x').zfill(8) + # ctypes.c_int32 эмулирует JS 32-битный signed int при сдвиге + shifted = ctypes.c_int32(hash_val << 5).value + hash_val = shifted + hash_val + ord(char) + + # В JS: Math.abs(hash).toString(16).padStart(8, '0') + return format(abs(hash_val), 'x').zfill(8) @router.post("/check-ocr-status")