← всі звіти · 02-pseudocode.md

sparc_phase: P project: pediatric-news created: 2026-05-11 author: claude-vps status: draft spec_link: ./01-specification.md

Pseudocode — Pediatric News (Telegram + Threads + Infographic)

High-level flow

Cron tick спрацьовує 3×/день. Pipeline робить fan-in (RSS+select) → fan-out на 3 паралельні output'и (Telegram-пост з PNG, Threads-thread, лог). seen_ids.json — точка дедуплікації, оновлюється після успіху Telegram (мінімальний commitment).

Основний flow

1. CRON tick @ 05:00 / 11:00 / 17:00 UTC
2. load_seen()  # set з seen_ids.json
3. articles = fetch_rss(MAX_AGE_HOURS=90)
   3a. для кожного з 5 RSS-feed'ів → перші 10 entries, filter за cutoff
   3b. помилка одного feed — log + continue
4. new_articles = articles - seen
   4a. якщо порожньо → exit «no new articles»
5. selected = gemini_select_and_format(new_articles[:15])
   5a. retry 1× з batch=8 якщо timeout
   5b. якщо all fail → log error, exit
6. selected містить: {source_article, telegram_html, summary, link, journal}
7. FAN-OUT (паралельно через threads / asyncio.gather):
   ├── 7a. infographic_pipeline(selected)
   ├── 7b. telegram_pipeline(selected, png_path_future)
   └── 7c. threads_pipeline(selected)
8. join fan-out → collect (tg_ok, threads_ok, png_ok)
9. якщо tg_ok → seen.add(selected.id); save_seen()
10. log_metrics({tg_ok, threads_ok, png_ok, timings})

Альтернативні flows / сценарії помилок

Scenario 1: Gemini timeout

gemini_call(batch_15, timeout=60)
  → TimeoutError → retry with batch_8, timeout=45
  → still fail → log "[Gemini] hard fail" + exit без поста

Scenario 2: Threads reply падає (permission error)

threads_publish(root)        → OK, root_id збережено
threads_publish(reply_1)     → 403 permission
  → log warning, НЕ блокуємо tg_ok, root залишається у фіді одиничним
  → daily-metrics позначає depth=1 замість 3

Scenario 3: PIL render fail

render_png(spec)
  → Exception (шрифт missing / spec невалідний)
  → telegram_pipeline отримує png=None → sendMessage (text-only) замість sendPhoto
  → log degraded

Ключові структури даних

Псевдо-функції / responsibilities

Інтеграції зі сторонніми системами

Що НЕ робимо у логіці

Відкриті питання

  1. Чи робити fan-out справді паралельним (asyncio) чи послідовним для простоти debug?
  2. Caption Telegram-photo має 1024-char limit — обрізати чи робити sendPhoto+sendMessage у threadi?
  3. Threads-thread треба будувати з тих самих machine-фактів (N, journal, year) чи окремо запускати Gemini ще раз на summary?

Sign-off

🤖 PM Changelog