daily-sync

Daily Sync

Раз на добу (тригериться при першому кліку оператора в діалозі за день) — оновити статичні дані діалогу у векторній базі і зафіксувати snapshot у Supabase.

Що синхронізуємо

ДжерелоДія
Профіль RUЗапит через ProfileService.fetchRu() → hash JSON → порівняти з останнім snapshot → якщо змінився, оновити profile/photo chunks у векторі.
Профіль TUТак само через ProfileService.fetchTu().
Фото профілюURL витягується з профілю. Якщо hash URL змінився — profile/photo chunks перебудовуються. TODO: додати vision-аналіз фото і запис текстового опису в source='photo'.
AI-нотаткиNotesService.fetchFresh(since=lastNoteAt) → ingest у вектор як source: 'note' + snapshot.

Чому так

  • Профіль і фото міняються рідко — щоденного перерахунку достатньо, нема сенсу робити це на кожен запит.
  • Нотатки за добу формуються асинхронно (AI-pipeline над діалогом). Daily sync — точка дотику між тим pipeline і нашою памʼяттю.
  • Переписка не входить у daily sync — її дотягуємо ліниво при кліку «Згенерувати» (generation-pipeline), бо її свіжість критично важлива.

Кроки

  1. Перевірити tips_daily_entity_snapshots для dialog_key + sync_date=today + entity_type=profile. Якщо сьогодні вже є RU і TU profiles, скіпаємо daily sync і повертаємо cached profiles.
  2. Профіль:
    • GET profile from upstream (RU + TU).
    • Прочитати останні profile snapshots з Supabase.
    • Hash diff → якщо змінилось, видалити старі profile/photo chunks з вектора + ingest нові.
  3. Фото:
    • Порівняти hash { url } з останнім photo snapshot.
    • Якщо змінилось разом з profile refresh — перебудувати photo/profile chunks.
    • TODO: якщо URL новий або photo analysis відсутній, запустити photo-analysis-ingest і записати текстовий опис фото у client_memory_chunks.
  4. Нотатки:
    • Запит до upstream API: getNotes(ruId, tuId, since=lastNoteAt).
    • Нові нотатки → ingest у вектор як source: 'note'.
  5. Upsert snapshots у tips_daily_entity_snapshots: profile, photo, note, marker daily_sync.

Дані

tips_daily_entity_snapshots зберігає короткоживучий audit/cache на 14 днів:

  • dialog_key, family, ru_id, tu_id
  • sync_date, entity_type, source_role, source_id
  • payload, content_hash, entity_at, text
  • unique key: (dialog_key, sync_date, entity_type, source_role, source_id)

Зв’язки

TODO

  • Перевірити cleanup для expires_at у tips_daily_entity_snapshots.
  • Вирішити чи photo hash має бути тільки URL, чи content hash картинки.
  • Додати PhotoAnalysisService: не передавати тільки screenshot/photoUrl, а зберігати vision summary у базу.