What I would change
The public site came after the Mini App, and the schema still shows the order in which things happened: orders.telegram_id is nullable and every order carries a source of telegram or web, but users and carts are keyed by a Telegram id. A web buyer can place an order and cannot have a cart or a history. That is a real seam, not a cosmetic one. Starting again, the account model would be identity-agnostic from the first migration instead of Telegram-first with a web exception bolted on.