36 lines
3.2 KiB
SQL
36 lines
3.2 KiB
SQL
SET search_path TO analytics, public;
|
|
-- Only enrich the bundled synthetic histories; unknown real purchase dates stay NULL.
|
|
UPDATE gamepass_ownership o SET purchased_at=p.first_seen+(p.last_seen-p.first_seen)*((p.id*31+o.gamepass_id)%100/100.0)
|
|
FROM players p,games g WHERE p.id=o.player_id AND p.game_id=o.game_id AND g.id=o.game_id
|
|
AND g.sample_key IN ('willow-v1','orbit-v1','dungeon-v1') AND o.is_owned AND o.purchased_at IS NULL;
|
|
INSERT INTO interaction_events(game_id,kind,report_key,player_id,session_id,product_id,receipt_id,started_at,ended_at,outcome,properties)
|
|
SELECT s.game_id,'product_prompt','receipt-'||s.receipt_id,s.player_id,s.session_id,s.product_id,s.receipt_id,
|
|
greatest(se.started_at,s.purchased_at-(3+s.id%29)*interval '1 second'),s.purchased_at,'bought','{"synthetic":true}'
|
|
FROM product_sales s JOIN sessions se ON se.game_id=s.game_id AND se.id=s.session_id JOIN games g ON g.id=s.game_id
|
|
WHERE g.sample_key IN ('willow-v1','orbit-v1','dungeon-v1') ON CONFLICT DO NOTHING;
|
|
INSERT INTO interaction_events(game_id,kind,report_key,player_id,session_id,product_id,started_at,ended_at,outcome,properties)
|
|
SELECT s.game_id,'product_prompt','closed-session-'||s.id,s.player_id,s.id,p.id,
|
|
s.started_at+(s.ended_at-s.started_at)*.3,
|
|
CASE WHEN s.id%97=0 THEN NULL ELSE least(s.ended_at,s.started_at+(s.ended_at-s.started_at)*.3+(1+s.id%21)*interval '1 second') END,
|
|
CASE WHEN s.id%97=0 THEN NULL ELSE 'closed' END,'{"synthetic":true}'
|
|
FROM sessions s JOIN games g ON g.id=s.game_id JOIN products p ON p.game_id=s.game_id
|
|
AND p.roblox_product_id=8000000+s.game_id*100+1+s.id%4
|
|
WHERE g.sample_key IN ('willow-v1','orbit-v1','dungeon-v1') AND s.ended_at-s.started_at>interval '1 minute' AND s.id%3=0
|
|
ON CONFLICT DO NOTHING;
|
|
-- Product prompt telemetry is separate from the longer shop/activity journey.
|
|
-- Source labels below are synthetic examples, never inferred for real reports.
|
|
UPDATE interaction_events i SET trigger_source=CASE WHEN i.id%100<5 THEN 'unknown'
|
|
WHEN i.outcome='bought' AND i.id%100<85 THEN 'player'
|
|
WHEN i.outcome IS DISTINCT FROM 'bought' AND i.id%100<30 THEN 'player' ELSE 'game' END,
|
|
properties=i.properties||'{"sourceSeeded":true}'::jsonb
|
|
FROM games g WHERE i.game_id=g.id AND g.sample_key IN ('willow-v1','orbit-v1','dungeon-v1')
|
|
AND i.properties->>'synthetic'='true' AND NOT(i.properties ? 'sourceSeeded');
|
|
UPDATE activity_runs a SET prompt_count=0,outcome=CASE WHEN outcome='purchased' THEN 'closed' ELSE outcome END,
|
|
step_count=CASE WHEN stage_progress ? 'product_viewed' THEN 1 ELSE 0 END,
|
|
captured_values=captured_values-'product_id'-'purchase_amount',
|
|
stage_progress=(SELECT coalesce(jsonb_agg(e),'[]'::jsonb) FROM jsonb_array_elements(a.stage_progress) e WHERE e NOT IN ('"buy_prompt_shown"'::jsonb,'"purchase_completed"'::jsonb))
|
|
FROM activity_definitions d,games g WHERE d.id=a.definition_id AND d.game_id=a.game_id AND g.id=a.game_id
|
|
AND g.sample_key IN ('willow-v1','orbit-v1','dungeon-v1') AND d.key='shop';
|
|
UPDATE activity_definitions d SET configuration=jsonb_build_object('steps',jsonb_build_array('product_viewed'),'fields',jsonb_build_array('currency_balance'))
|
|
FROM games g WHERE d.game_id=g.id AND g.sample_key IN ('willow-v1','orbit-v1','dungeon-v1') AND d.key='shop';
|