feat(mailsync): FetchMailFolder — integration-layer mail walk for ETL consumers (2dph) #4

Merged
eSlider merged 1 commits from feat/2dph-mail-integration-layer into main 2026-08-31 10:08:20 +01:00
Collaborator

Что это

Первый шаг к #1 («Integration layer for 2dph: canonical OnlyOffice SDK/client reuse»): высокоуровневый обход почтовой папки прямо в библиотеке — Client.FetchMailFolder — вместо того, чтобы каждый потребитель (2dph brain mail-ingest, cv-тулзы) reimplement'ил цикл list → get → download против приватных копий клиента.

API

type MailSyncMessage struct {
    ID             int64
    Folder         int
    Subject        string
    From           string // raw RFC 5322
    Date           time.Time
    IsNew          bool
    HasAttachments bool
    Attachments    []MailSyncAttachment // ID/Name/Size (+Body при FetchBodies)
}

msgs, err := c.FetchMailFolder(ctx, onlyoffice.MailFolderInbox,
    onlyoffice.MailSyncOptions{Limit: 100, FetchBodies: true})

Опции: Limit / StartIndex — окна для чекпойнт-обхода; FetchBodies — сразу скачать байты вложений через download.ashx (session-cookie путь уже покрыт cookie jar клиента).

Детали гидрации

  • элементы списка могут не содержать массив attachments: при hasAttachments подтягивается полный рекорд (GetMailMessage) и вложения мержатся;
  • id вложения принимается из вариантов id / fileId / attachmentId;
  • таймстампы: RFC3339 с любым числом долей секунды + форма без долей; неразбираемое → нулевое время (не ошибка).

Тесты

httptest-мок: пагинация и остановка на короткой странице, фолбэк к полному рекорду при hasAttachments без массива, скачивание тела с требованием auth-cookie, окна Limit/StartIndex, парсинг времён.

Как это связано с 2dph

Ветка feat/imap-mailsync-v1 в eSlider/2dph (PR #107) портирует IMAP-источник и фиксы write-пути brain; следующим шагом внутренний минималистичный OOClient (internal/mailsync/onlyoffice.go, raw HTTP) заменяется на этот канонический фасад. Отчёт расследования: eSlider/2dph#106.

Closes #1 частично (шаг 1: canonical walk в SDK).

## Что это Первый шаг к #1 («Integration layer for 2dph: canonical OnlyOffice SDK/client reuse»): высокоуровневый обход почтовой папки прямо в библиотеке — `Client.FetchMailFolder` — вместо того, чтобы каждый потребитель (2dph brain mail-ingest, cv-тулзы) reimplement'ил цикл list → get → download против приватных копий клиента. ## API ```go type MailSyncMessage struct { ID int64 Folder int Subject string From string // raw RFC 5322 Date time.Time IsNew bool HasAttachments bool Attachments []MailSyncAttachment // ID/Name/Size (+Body при FetchBodies) } msgs, err := c.FetchMailFolder(ctx, onlyoffice.MailFolderInbox, onlyoffice.MailSyncOptions{Limit: 100, FetchBodies: true}) ``` Опции: `Limit` / `StartIndex` — окна для чекпойнт-обхода; `FetchBodies` — сразу скачать байты вложений через download.ashx (session-cookie путь уже покрыт cookie jar клиента). ## Детали гидрации - элементы списка могут не содержать массив attachments: при `hasAttachments` подтягивается полный рекорд (`GetMailMessage`) и вложения мержатся; - id вложения принимается из вариантов `id` / `fileId` / `attachmentId`; - таймстампы: RFC3339 с любым числом долей секунды + форма без долей; неразбираемое → нулевое время (не ошибка). ## Тесты httptest-мок: пагинация и остановка на короткой странице, фолбэк к полному рекорду при hasAttachments без массива, скачивание тела с требованием auth-cookie, окна Limit/StartIndex, парсинг времён. ## Как это связано с 2dph Ветка `feat/imap-mailsync-v1` в eSlider/2dph (PR #107) портирует IMAP-источник и фиксы write-пути brain; следующим шагом внутренний минималистичный OOClient (`internal/mailsync/onlyoffice.go`, raw HTTP) заменяется на этот канонический фасад. Отчёт расследования: eSlider/2dph#106. Closes #1 частично (шаг 1: canonical walk в SDK).
Owner

Ревью-замечание (PO): ветка отстала от main на 49 коммитов (main ушёл вперёд после рефакторинга и фич). Пожалуйста, ребейзни ветку на актуальный main (git rebase main) и разреши конфликты, затем force-push. CI перезапустится. После этого PR готов к полному ревью и вливанию.

Контекст: feature уникальна (FetchMailFolder для 2dph ETL) и нужна, но требует чистой истории против текущего main.

Ревью-замечание (PO): ветка отстала от main на 49 коммитов (main ушёл вперёд после рефакторинга и фич). Пожалуйста, ребейзни ветку на актуальный main (git rebase main) и разреши конфликты, затем force-push. CI перезапустится. После этого PR готов к полному ревью и вливанию. Контекст: feature уникальна (FetchMailFolder для 2dph ETL) и нужна, но требует чистой истории против текущего main.
eSlider added 1 commit 2026-08-31 10:07:25 +01:00
feat(mailsync): FetchMailFolder — integration-layer walk for ETL consumers
Release Please / Release Please (push) Skipped
Release / GoReleaser (push) Skipped
Tests / Secret scan (gitleaks) (push) Skipped
Tests / Test (Go 1.25) (push) Skipped
Tests / Test (Go stable) (push) Skipped
Tests / Secret scan (gitleaks) (pull_request) Successful in 5s
Tests / Test (Go 1.25) (pull_request) Successful in 24s
Tests / Test (Go stable) (pull_request) Successful in 40s
35f0cb8d20
Adds the high-level mail folder walk that sync pipelines need on top of
the raw mail API (list -> get -> download-attachment), so consumers stop
re-implementing it against private client copies.

  type MailSyncMessage struct { ID, Folder, Subject, From, Date, IsNew,
                                HasAttachments, Attachments }
  type MailSyncAttachment struct { ID, Name, Size, Body }
  func (c *Client) FetchMailFolder(ctx, folderID, MailSyncOptions)
                                   ([]MailSyncMessage, error)

Options: Limit / StartIndex for checkpointed walks, FetchBodies to
eagerly download attachment bytes via download.ashx (session-cookie path).

Hydration details:
- list items may omit the attachment array; when hasAttachments is set
  the full record is fetched and its attachments merged
- attachment ids accepted from id/fileId/attachmentId variants
- timestamps parsed from RFC3339 (any fractional digits) and
  second-precision forms

This is the first step of the 2dph integration layer (#1): the brain's
mail-ingest pipeline can now drop its private OOClient copy and consume
this canonical walk directly.

Tests: httptest-backed coverage for pagination, hydration with
full-record fallback, body download incl. auth-cookie requirement,
Limit/StartIndex windows, timestamp parsing.
eSlider force-pushed feat/2dph-mail-integration-layer from ae776aa396 to 35f0cb8d20 2026-08-31 10:07:25 +01:00 Compare
eSlider merged commit 93828ee19d into main 2026-08-31 10:08:20 +01:00
eSlider deleted branch feat/2dph-mail-integration-layer 2026-08-31 10:08:20 +01:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: eSlider/go-onlyoffice#4