fix(backend): исправлен алгоритм hash для совместимости с JS

- Использован ctypes.c_int32 для эмуляции JS 32-битного сдвига
- Теперь Python hash совпадает с JS hash в n8n
- Кэширование form_draft работает корректно
This commit is contained in:
Fedor
2025-11-30 11:37:16 +03:00
parent 3801bc4949
commit 0f8631bf20

View File

@@ -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")