feat: классификация писем Qwen3:8b + обработчики (urgent→TG, task→VTODO, meeting→VEVENT)
- mail_archive.py: фикс вложений himalaya --dir → --downloads-dir; attachments/ только при has_attachment; идемпотентно - email_classifier.py: Qwen3:8b (Ollama) → теги info/urgent/task/meeting в frontmatter email.md - email_handlers.py: urgent→Telegram (Bot API+SOCKS5), task→Radicale VTODO, meeting→Radicale VEVENT; handled_* идемпотентность; --dry-run - .gitignore: игнор *.env.bak* - openspec: чейндж email-classification-handlers (в работе) - STATUS/TODO/WALKTHROUGH: прогресс сессии, подводные камни Radicale (http.client, Depth:1, формат дат)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
## Purpose
|
||||
|
||||
Создание задач через Radicale как VTODO-объектов в календаре «Задачи» (CalDAV).
|
||||
Используется обработчиком `task` в чейндже email-classification-handlers вместо
|
||||
Vikunja. Упрощает архитектуру: Radicale — единственный сервис календаря и задач.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Задача создаётся как VTODO в Radicale
|
||||
|
||||
Задача MUST создаваться как VTODO-объект (CalDAV) в календаре «Задачи» Radicale
|
||||
по адресу `https://cal.nixg.ru/estorozhenko/Задачи/`, а не через Vikunja API.
|
||||
|
||||
#### Scenario: Обработчик task
|
||||
- **WHEN** `email_handlers.py` обрабатывает письмо с тегом `task`
|
||||
- **THEN** в календаре «Задачи» Radicale создаётся VTODO (PUT по адресу
|
||||
`https://cal.nixg.ru/estorozhenko/<urlencoded Задачи>/<uid>.ics`)
|
||||
|
||||
### Requirement: Поля VTODO из письма
|
||||
|
||||
VTODO MUST содержать: SUMMARY — тема письма, DESCRIPTION — ссылка на файл
|
||||
`email.md` письма. При наличии даты/дедлайна в классификации — DTSTART/DUE.
|
||||
|
||||
#### Scenario: Создание VTODO из письма с задачей
|
||||
- **WHEN** `email_handlers.py` создаёт задачу из письма с тегом `task`
|
||||
- **THEN** VTODO имеет SUMMARY=тема письма, DESCRIPTION=путь к email.md,
|
||||
и (если указано) DTSTART/DUE из классификации
|
||||
|
||||
### Requirement: Идемпотентность задач Radicale
|
||||
|
||||
Повторный запуск обработчика MUST NOT создавать дубликат VTODO для одного письма
|
||||
(поле `handled_task: true` в frontmatter после успешного создания).
|
||||
|
||||
#### Scenario: Повторный запуск обработчика task
|
||||
- **WHEN** `email_handlers.py` запущен повторно на письме с уже созданной задачей (`handled_task: true`)
|
||||
- **THEN** новый VTODO не создаётся
|
||||
|
||||
### Requirement: Совместимость с jtx board / DAVx5
|
||||
|
||||
Созданный VTODO MUST быть читаемым стандартными CalDAV-клиентами (jtx board,
|
||||
DAVx5), т.е. валидным VCALENDAR с VTODO компонентом.
|
||||
|
||||
#### Scenario: Чтение задачи в jtx board
|
||||
- **WHEN** пользователь открывает календарь «Задачи» в jtx board (через DAVx5)
|
||||
- **THEN** VTODO отображается как задача с SUMMARY и DESCRIPTION
|
||||
Reference in New Issue
Block a user