Posts can now be sourced from multiple VK groups, each routed to its own
Telegram/MAX destination(s) with independent on/off switches, configured
via data/routes.json (supports // line comments). Falls back to a single
route auto-generated from the legacy VK_SOURCE/TG_CHAT_ID/MAX_CHAT_ID env
vars if routes.json doesn't exist yet, so existing deployments keep working.
Routes are processed strictly sequentially within a cycle (no concurrency)
to keep flood control on VK/TG/MAX correct, since bot tokens are shared
across routes. DB schema gains route_id in the posts uniqueness key so the
same VK donor can safely feed multiple routes without status collisions.
Also removes the trailing-hashtag-stripping logic in text_formatter, which
was silently deleting VK posts' own hashtags whenever COMMON_TAGS wasn't
configured (it always wasn't) - posts are now forwarded unchanged.
- Stop blindly retrying send_photo/send_video/send_media_group and MAX
send_message on ambiguous network timeouts - a timeout doesn't prove
the message wasn't delivered, and retrying risked posting duplicates
(observed live: a video posted 3-5x after repeated timeout retries).
- Raise/rework timeouts that were too short for real large-file transfer
speeds: TG media upload timeout, and yt-dlp download now uses stall
detection (killed only on true silence) instead of a flat ceiling that
was cutting off legitimately slow-but-successful video downloads.
- Fix sendRichMessage: ok=true with an unparseable message_id no longer
triggers a fallback send (Telegram already created the message).
- MAX: videos over the documented 250MB cap are now sent as a "watch via
link" note instead of silently failing the upload.
- Add PRAGMA busy_timeout to all DB connections.
- Remove unused MAX_MEDIA_CHANNEL_ID (MAX's /uploads returns a portable
token directly, no staging channel needed, unlike Telegram).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>