Fixed
- An archive holding messages whose chat no longer exists can now upgrade. The first real production archive to attempt the 8.0 upgrade was refused by it: years of Telegram's group→supergroup renumbering had left messages and sync rows whose
chatsrow was long gone, and recreating the composite foreign keys re-checks every row, so migration022aborted on the first orphan it met — on PostgreSQL these rows hide behind aconvalidatedflag that still reads true, because the bulk copies that let them in (the SQLite→PostgreSQL mover among them) run with enforcement disabled and nothing ever re-checks. The transaction rolled back cleanly, exactly as designed, but a refusal keeps that history hostage on 7.x forever — and an archive old enough to carry renumbering scars is precisely the archive 8.0 exists for. Migration022now creates a neutral placeholder chat for every distinct chat id thatmessages,sync_status,forum_topicsorchat_folder_membersstill references andchatsno longer holds — typed by the id pattern alone, empty title, never anything derived from message content — before it touches those tables. The placeholders ride the same machinery as every real chat (account 1, minted ref, recreated keys), so the formerly orphaned history becomes first-class and the viewer serves it under its placeholder chat: after this upgrade you may find chats with no title in your sidebar, and they are exactly that recovered history. SQLite archives carried the same orphans through022silently instead of failing on them; the same step now heals them too, so both backends land on the same end state. The one case this cannot reach is a SQLite archive that already completed the 8.0.0 upgrade with orphans aboard —022never runs twice, so that history stays as unreachable as it was on 7.x. (#308)
📋 Full changelog: docs/CHANGELOG.md