8 Commits

Author SHA1 Message Date
Andrey Epifancev
7d8a506f4d fix(hotfolder): ошибка открытия входящего файла не удаляет файл прошлой доставки (#26, I-1)
Открытие вынесено из блока снятия недописанного файла: при SCAN_CLEANUP=true
удаляется только файл, сбойнувший после открытия. Решения R-5…R-8 — в design.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:54:54 +04:00
Andrey Epifancev
6870ca799a feat(smb): запись прямо в Input с перезаписью, как в старом АРМ (#26)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 16:30:31 +04:00
Andrey Epifancev
a65ff8cf40 test: SMB-очистка и коллизии rename, проверки очистки в воркере, точные докстринги
- F-D: фейк rename бросает SMBOSError(STATUS_OBJECT_NAME_COLLISION) (и обычный FileExistsError), rmdir — STATUS_DIRECTORY_NOT_EMPTY;
  тесты validate_name, сирот .part/.done, access-denied scandir, подкаталога в Output, .part при существующем назначении,
  учётных данных во всех вызовах очистки; докстринг SmbHotFolder.put больше не противоречит сам себе (T12.5)
- F-E: тест ошибки очистки проверяет вызов очистки и ровно одну строку WARNING
- T9.4: докстринг протокола Normalizer; T13.4: устаревшие ссылки на «Task 14»; мёртвый noqa BLE001 в worker.py

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-07 03:35:10 +04:00
Andrey Epifancev
c00823c673 feat(hotfolder): SMB — rename без замены и cleanup под флагом (D-1, D-2) 2026-10-07 01:21:51 +04:00
Andrey Epifancev
83e55af941 Срез 0 [7.2, fix T2.1 T2.2 T2.4]: горячие папки — повторный листинг после чтения, ENOTDIR в SMB
- T2.1: после чтения набора каталог ответа листается заново (Local и SMB); если снимок (имена и
  размеры) отличается от настоявшегося — None, набор настаивается заново.
- T2.2: SmbHotFolder — ENOTDIR из листинга Output/<job_id> (на месте каталога файл) — None,
  как у LocalHotFolder.
- T2.4: тест SMB — ENOENT / SHARING_VIOLATION / ENOTDIR во время настаивания сбрасывают
  накопленное состояние settle (pending_jobs() == 0).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:18:29 +04:00
Andrey Epifancev
e8453159e8 Срез 0 [7.1]: горячие папки — набор *.json ответа, готовность по settle, служебный каталог Tmp
- HotFolder.poll(job_id) -> list[AnswerFile] | None: все *.json каталога <output>/<job_id>/ по возрастанию
  имени, когда набор не пуст и имена/размеры не менялись SCAN_SETTLE_SECONDS (SettleTracker: состояние по
  job_id, внедряемые часы, сброс при выдаче/опустении, предел 1024 задания, потокобезопасно);
- put: временный .<name>.part в <корень>/<SCAN_TMP_DIR>/ (создаётся), rename в Input (Local и SMB);
- настройки SCAN_TMP_DIR (Tmp) и SCAN_SETTLE_SECONDS (2, >= 0); в .env.test settle = 0 (R-23);
- воркер: переходная прослойка — берётся первый файл набора (склейка всех — Task 3, R-22).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:01:39 +04:00
Andrey Epifancev
5fb046fced Срез 0 [4.2] T8.1-T8.3: inbox_name заменяет символы Windows/SMB, poll ждёт занятый файл, put терпит отказ mkdir при существующем Input
T8.1: inbox_name заменяет `: < > " | ? *` и управляющие символы на `_`, убирает завершающие точки/пробелы;
ValueError только если имени не осталось. validate_name/put остаются строгими.
T8.2: SmbHotFolder.poll возвращает None на STATUS_SHARING_VIOLATION/STATUS_DELETE_PENDING (ИС ещё пишет ответ),
монопольное открытие сохранено.
T8.3: при ошибке mkdir, кроме EEXIST/ENOENT, put продолжает, если smbclient.path.isdir(Input); иначе исходная ошибка.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 03:05:02 +04:00
Andrey Epifancev
1695573b35 Срез 0 [4.2]: SmbHotFolder поверх smbclient (src/gateway/smb.py), фабрика create_hotfolder, unit-тесты, отметка задачи
SmbHotFolder: UNC-корень \\host\SMB_PATH (или полный UNC в SMB_PATH), put — `.<name>.part` + smbclient.replace,
poll — open_file(rb), ENOENT (в т.ч. нет каталога) -> None, healthy — listdir корня без исключений.
create_hotfolder(settings): local -> LocalHotFolder, smb -> SmbHotFolder с ленивым импортом модуля (R-6);
отсутствие импорта src.gateway.smb в режиме local проверяется в отдельном интерпретаторе.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 02:57:31 +04:00