-- Stars 本地账本:per-user 余额 + 交易流水。此前 payments.getStarsStatus 余额恒 0、 -- getStarsTransactions 未注册、sendPaidReaction 恒返 BALANCE_TOO_LOW——无任何余额持久化。 -- 本地账本(非真实支付):起始余额走惰性首读授予(granted 布尔幂等,新老账号都覆盖、免回填)。 -- 借记原子性由 store 层 withTx 保证(SELECT ... FOR UPDATE + CHECK(balance>=0) + UPDATE + INSERT)。 CREATE TABLE public.stars_balances ( user_id bigint NOT NULL, balance bigint DEFAULT 0 NOT NULL, granted boolean DEFAULT false NOT NULL, updated_at timestamp with time zone DEFAULT now() NOT NULL, CONSTRAINT stars_balances_pkey PRIMARY KEY (user_id), CONSTRAINT stars_balances_balance_nonneg CHECK ((balance >= 0)) ); -- 流水:amount 带符号(贷记 > 0 / 借记 < 0);peer_* 为对手方(grant/topup 等无对手时为空)。 CREATE TABLE public.stars_transactions ( id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL, user_id bigint NOT NULL, peer_type text DEFAULT '' NOT NULL, peer_id bigint DEFAULT 0 NOT NULL, amount bigint NOT NULL, reason text DEFAULT 'adjust' NOT NULL, title text DEFAULT '' NOT NULL, description text DEFAULT '' NOT NULL, date integer DEFAULT 0 NOT NULL, CONSTRAINT stars_transactions_pkey PRIMARY KEY (id) ); -- keyset 分页:WHERE user_id=$1 [AND id < cursor] ORDER BY id DESC LIMIT n。 CREATE INDEX stars_transactions_user_id_idx ON public.stars_transactions USING btree (user_id, id DESC);