fix(stargifts): sync correct channel gift notifications
This commit is contained in:
parent
9ac63f8006
commit
5433801380
19 changed files with 893 additions and 26 deletions
|
|
@ -0,0 +1,9 @@
|
|||
DELETE FROM star_gift_user_message_refs refs
|
||||
USING peer_star_gifts gift
|
||||
WHERE gift.id = refs.saved_gift_id
|
||||
AND gift.owner_peer_type = 'channel';
|
||||
|
||||
COMMENT ON TABLE star_gift_user_message_refs IS
|
||||
'Owner-local private service-message aliases to user-owned saved gift aggregates.';
|
||||
|
||||
DROP TABLE IF EXISTS star_gift_channel_notification_jobs;
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
-- Channel gift purchases commit a durable recipient snapshot before any
|
||||
-- private notification is attempted. Delivery is idempotent and restart-safe:
|
||||
-- the deterministic private-send replay is authoritative if a process stops
|
||||
-- after writing the message but before marking this job delivered.
|
||||
CREATE TABLE star_gift_channel_notification_jobs (
|
||||
saved_gift_id bigint NOT NULL REFERENCES peer_star_gifts(id) ON DELETE CASCADE,
|
||||
target_user_id bigint NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
gift_date integer NOT NULL,
|
||||
action jsonb NOT NULL,
|
||||
attempts integer NOT NULL DEFAULT 0,
|
||||
next_attempt_at integer NOT NULL,
|
||||
lease_until integer NOT NULL DEFAULT 0,
|
||||
delivered_at integer NOT NULL DEFAULT 0,
|
||||
message_id integer NOT NULL DEFAULT 0,
|
||||
last_error text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (saved_gift_id, target_user_id),
|
||||
CONSTRAINT star_gift_channel_notification_jobs_state_check CHECK (
|
||||
saved_gift_id > 0
|
||||
AND target_user_id > 0
|
||||
AND gift_date > 0
|
||||
AND attempts >= 0
|
||||
AND next_attempt_at > 0
|
||||
AND lease_until >= 0
|
||||
AND delivered_at >= 0
|
||||
AND message_id >= 0
|
||||
AND ((delivered_at = 0 AND message_id = 0) OR (delivered_at > 0 AND message_id > 0))
|
||||
)
|
||||
);
|
||||
|
||||
CREATE INDEX star_gift_channel_notification_jobs_pending_idx
|
||||
ON star_gift_channel_notification_jobs(next_attempt_at, lease_until, saved_gift_id, target_user_id)
|
||||
WHERE delivered_at = 0;
|
||||
|
||||
COMMENT ON TABLE star_gift_channel_notification_jobs IS
|
||||
'Purchase-time snapshot of per-admin channel gift notification intents; delivery uses deterministic private-message replay.';
|
||||
|
||||
COMMENT ON TABLE star_gift_user_message_refs IS
|
||||
'Viewer-local private service-message aliases to saved gift aggregates; the saved gift owner may be that user or an authorized channel.';
|
||||
|
||||
-- Existing testserver/users already have channel prepaid/upgrade notifications.
|
||||
-- Backfill only aliases that are cryptographically unnecessary to guess: the
|
||||
-- persisted action itself names a channel and saved_id, and that exact pair
|
||||
-- must resolve to one saved gift. This changes no message, PTS or outbox row.
|
||||
WITH ordinary AS (
|
||||
SELECT box.owner_user_id,
|
||||
box.box_id,
|
||||
gift.id AS saved_gift_id
|
||||
FROM message_boxes box
|
||||
JOIN peer_star_gifts gift
|
||||
ON gift.owner_peer_type = 'channel'
|
||||
AND (box.media #>> '{service_action,star_gift,peer_channel_id}') ~ '^[1-9][0-9]*$'
|
||||
AND gift.owner_peer_id = (box.media #>> '{service_action,star_gift,peer_channel_id}')::bigint
|
||||
AND (box.media #>> '{service_action,star_gift,saved_id}') ~ '^[1-9][0-9]*$'
|
||||
AND gift.saved_id = (box.media #>> '{service_action,star_gift,saved_id}')::bigint
|
||||
WHERE NOT box.deleted
|
||||
AND box.media #>> '{service_action,kind}' = 'star_gift'
|
||||
AND gift.lifecycle_status = 'active'
|
||||
), collectible AS (
|
||||
SELECT box.owner_user_id,
|
||||
box.box_id,
|
||||
gift.id AS saved_gift_id
|
||||
FROM message_boxes box
|
||||
JOIN peer_star_gifts gift
|
||||
ON gift.owner_peer_type = 'channel'
|
||||
AND box.media #>> '{service_action,star_gift_unique,peer,Type}' = 'channel'
|
||||
AND (box.media #>> '{service_action,star_gift_unique,peer,ID}') ~ '^[1-9][0-9]*$'
|
||||
AND gift.owner_peer_id = (box.media #>> '{service_action,star_gift_unique,peer,ID}')::bigint
|
||||
AND (box.media #>> '{service_action,star_gift_unique,saved_id}') ~ '^[1-9][0-9]*$'
|
||||
AND gift.saved_id = (box.media #>> '{service_action,star_gift_unique,saved_id}')::bigint
|
||||
AND (box.media #>> '{service_action,star_gift_unique,gift,ID}') ~ '^[1-9][0-9]*$'
|
||||
AND gift.unique_gift_id = (box.media #>> '{service_action,star_gift_unique,gift,ID}')::bigint
|
||||
WHERE NOT box.deleted
|
||||
AND box.media #>> '{service_action,kind}' = 'star_gift_unique'
|
||||
AND gift.lifecycle_status = 'active'
|
||||
), aliases AS (
|
||||
SELECT * FROM ordinary
|
||||
UNION
|
||||
SELECT * FROM collectible
|
||||
)
|
||||
INSERT INTO star_gift_user_message_refs(owner_user_id, msg_id, saved_gift_id)
|
||||
SELECT owner_user_id, box_id, saved_gift_id
|
||||
FROM aliases
|
||||
ON CONFLICT(owner_user_id, msg_id) DO UPDATE
|
||||
SET saved_gift_id = EXCLUDED.saved_gift_id
|
||||
WHERE star_gift_user_message_refs.saved_gift_id = EXCLUDED.saved_gift_id;
|
||||
Loading…
Add table
Add a link
Reference in a new issue