openspec: архив 14 завершённых change-ов (веб-фиксы, crawler-queue, own-content-hub, publisher-service); спеки влиты в openspec/specs

This commit is contained in:
kpa39l
2026-09-16 17:01:00 +00:00
parent 584582a48c
commit 771f6a8276
88 changed files with 1632 additions and 3 deletions
+48
View File
@@ -0,0 +1,48 @@
# Tasks: rss-crawler
## 1. Схема и конфиг
- [x] 1.1 db/schema.sql: + CREATE TABLE rss_state; sources + feed_url; db/db.py — миграция ALTER TABLE (feed_url); sources.py — синк feed_url
Проверка: `python -m db.db` (init_db) выполняется без ошибок; таблица rss_state и колонка sources.feed_url появляются
- [x] 1.2 config.py: + RSS_USER_AGENT (env, default "vesti-rss/0.1"), RSS_DEFAULT_TIMEOUT=20
Проверка: `python -c "from config import RSS_USER_AGENT; print(RSS_USER_AGENT)"` → значение из .env
- [x] 1.3 requirements.txt: + trafilatura, selectolax
Проверка: `.venv/bin/pip install -r requirements.txt` без ошибок
## 2. Модуль краулера
- [x] 2.1 crawler/rss_crawler.py: normalize_url (UTM/якоря), sha256_text
Проверка: изолированный тест normalize_url: utm-параметры удаляются, якорь удаляется, остальное сохраняется
- [x] 2.2 fetch_feed: httpx.GET с If-None-Match/If-Modified-Since/User-Agent, таймаут, ретрай 429/503; 304 → пусто
Проверка: повторный запрос к ленте с etag → 304 (сервер LWN поддерживает)
- [x] 2.3 parse_entries: feedparser, извлечение etag/modified из ответа, лимит записей (MAX_ITEMS=25)
Проверка: запись → dict {url, title, text, published_at, author}
- [x] 2.4 full_text: trafilatura для summary-only (selectolax для HTML→text)
Проверка: запись с summary → в text полный текст или summary (не падает)
- [x] 2.5 store_rss_post: дедуп по sha256; вставка в posts (source_id, url, canonical_url, content_type='text', published_at)
Проверка: две идентичные записи → одна строка в posts
- [x] 2.6 run_source: start_run/finish_run, обновление rss_state (etag/modified/status/error_count), status alive/dead при error_count>=5
Проверка: успешный прогон → rss_state.status='alive', runs=ok; имитация ошибки → error_count растёт
- [x] 2.7 CLI: --all / --direction / --source / --dry-run
Проверка: `--source lwn --dry-run` печатает записи, БД не меняется
## 3. Источники и интеграция
- [x] 3.1 sources.yaml: + lwn (crawler: rss, direction: linux, priority: P0, enabled: true); пример opennet закомментирован
Проверка: `sync_sources_to_db()` — в БД появляется источник lwn c crawler='rss'
- [x] 3.2 .env.example: + RSS_USER_AGENT, RSS_DEFAULT_TIMEOUT
- [x] 3.3 Реальный прогон `--source lwn` → посты в posts, rss_state настроена
Проверка: SQL-запросы из design.md (Verification)
## 4. Cron и доки
- [ ] 4.1 Hermes cron: vesti-rss-crawler (`*/15`, P0; no_agent, тихий, deliver=local)
Проверка: cron list показывает job; ручной запуск проходит
- [x] 4.2 STATUS.md / AGENT.MD обновлены (команды запуска, порты/доступы)
Проверка: grep rss в доках
- [x] 4.3 `openspec validate rss-crawler` → 0 ошибок
Проверка: команда выше → valid
- [ ] 4.4 TODO.md: + задача веб-скедулинга RSS (веб-админ: кнопка запуска краулера)
Проверка: задача видна в планах
Открытый вопрос: состояние таблицы rss_state ERROR (после 429 и ретрая, error_count=1) обновится при следующем удачном 200; в отсутствие ошибок не трогаем.