feat(release): prepare 1.1.0 candidate

This commit is contained in:
Yun Chan 2026-08-29 18:33:45 +09:00
parent 5a34f66981
commit 5205dcdfa9
736 changed files with 115667 additions and 12203 deletions

View file

@ -0,0 +1,192 @@
\set ON_ERROR_STOP on
BEGIN;
CREATE OR REPLACE FUNCTION pg_temp.assert_true(condition boolean, message text)
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
IF condition IS NOT TRUE THEN
RAISE EXCEPTION 'assertion_failed: %', message;
END IF;
END;
$$;
INSERT INTO auth.users (
id, aud, role, email, encrypted_password, email_confirmed_at,
raw_app_meta_data, raw_user_meta_data, created_at, updated_at
) VALUES
(
'20000000-0000-4000-8000-000000000001', 'authenticated', 'authenticated',
'runtime-one@example.invalid', crypt('fixture-password', gen_salt('bf')), now(),
'{"provider":"email","providers":["email"]}'::jsonb, '{}'::jsonb, now(), now()
),
(
'20000000-0000-4000-8000-000000000002', 'authenticated', 'authenticated',
'runtime-two@example.invalid', crypt('fixture-password', gen_salt('bf')), now(),
'{"provider":"email","providers":["email"]}'::jsonb, '{}'::jsonb, now(), now()
);
UPDATE public.subscriptions
SET tier = 'free', status = 'active', overage_credits = 0
WHERE user_id IN (
'20000000-0000-4000-8000-000000000001',
'20000000-0000-4000-8000-000000000002'
);
SELECT pg_temp.assert_true(
NOT has_function_privilege(
'authenticated',
'public.grant_verified_ad_reward(uuid,text,text,text,text,integer)',
'EXECUTE'
),
'authenticated users must not grant their own ad rewards'
);
SELECT pg_temp.assert_true(
NOT has_table_privilege('authenticated', 'public.ad_reward_receipts', 'SELECT'),
'authenticated users must not read verified ad callback receipts'
);
SELECT pg_temp.assert_true(
has_function_privilege('authenticated', 'public.mobile_dashboard_stats()', 'EXECUTE'),
'authenticated users must be able to read their dashboard aggregate'
);
SELECT pg_temp.assert_true(
NOT has_function_privilege('anon', 'public.mobile_dashboard_stats()', 'EXECUTE'),
'anonymous users must not execute dashboard aggregates'
);
DO $$
DECLARE
first_claim jsonb;
duplicate_claim jsonb;
cooldown_claim jsonb;
cooldown_replay jsonb;
capped_claim jsonb;
balance integer;
BEGIN
first_claim := public.grant_verified_ad_reward(
'20000000-0000-4000-8000-000000000001',
'admob:fixture', 'rewarded_video_quota', '5224354917',
'runtime-reward-transaction-0001', 50
);
PERFORM pg_temp.assert_true((first_claim->>'granted')::boolean, 'first reward is granted');
duplicate_claim := public.grant_verified_ad_reward(
'20000000-0000-4000-8000-000000000001',
'admob:fixture', 'rewarded_video_quota', '5224354917',
'runtime-reward-transaction-0001', 50
);
PERFORM pg_temp.assert_true(
duplicate_claim->>'reason' = 'duplicate',
'transaction replay is idempotent'
);
cooldown_claim := public.grant_verified_ad_reward(
'20000000-0000-4000-8000-000000000001',
'admob:fixture', 'rewarded_video_quota', '5224354917',
'runtime-reward-transaction-0002', 50
);
PERFORM pg_temp.assert_true(
cooldown_claim->>'reason' = 'cooldown',
'distinct immediate callback is rate limited'
);
cooldown_replay := public.grant_verified_ad_reward(
'20000000-0000-4000-8000-000000000001',
'admob:fixture', 'rewarded_video_quota', '5224354917',
'runtime-reward-transaction-0002', 50
);
PERFORM pg_temp.assert_true(
cooldown_replay->>'reason' = 'duplicate',
'a cooldown receipt remains consumed and can never become grantable'
);
PERFORM pg_temp.assert_true(
(SELECT count(*) FROM public.ad_reward_claims
WHERE transaction_id = 'runtime-reward-transaction-0002') = 0,
'a replayed cooldown receipt never creates a grant claim'
);
SELECT overage_credits INTO balance FROM public.subscriptions
WHERE user_id = '20000000-0000-4000-8000-000000000001';
PERFORM pg_temp.assert_true(balance = 50, 'only one callback changes the balance');
INSERT INTO public.ad_reward_claims (
user_id, network, placement, ad_unit_id, transaction_id, reward_tokens, verified_at
)
SELECT
'20000000-0000-4000-8000-000000000002',
'admob:fixture', 'rewarded_video_quota', '5224354917',
'runtime-cap-' || lpad(number::text, 3, '0'), 50,
date_trunc('day', now()) + (number * interval '20 seconds')
FROM generate_series(1, 20) AS number;
capped_claim := public.grant_verified_ad_reward(
'20000000-0000-4000-8000-000000000002',
'admob:fixture', 'rewarded_video_quota', '5224354917',
'runtime-cap-overflow-transaction', 50
);
PERFORM pg_temp.assert_true(
capped_claim->>'reason' = 'daily_cap',
'daily reward cap is enforced before another credit grant'
);
END;
$$;
INSERT INTO public.history (
id, user_id, title, original_text, mode, status, duration, word_count,
app_version, created_at, updated_at
) VALUES
(
'21000000-0000-4000-8000-000000000001',
'20000000-0000-4000-8000-000000000001',
'Today', 'today transcript', 'dictation', 'completed', 60, 10,
'1.0.0', now(), now()
),
(
'21000000-0000-4000-8000-000000000002',
'20000000-0000-4000-8000-000000000001',
'Yesterday', 'yesterday transcript', 'file-transcription', 'completed', 120, 20,
'1.0.0', now() - interval '1 day', now() - interval '1 day'
),
(
'21000000-0000-4000-8000-000000000003',
'20000000-0000-4000-8000-000000000001',
'Older', 'older transcript', 'dictation', 'completed', 30, 5,
'1.0.0', now() - interval '3 days', now() - interval '3 days'
),
(
'21000000-0000-4000-8000-000000000004',
'20000000-0000-4000-8000-000000000001',
'Error', 'failed transcript', 'dictation', 'error', 999, 999,
'1.0.0', now(), now()
),
(
'21000000-0000-4000-8000-000000000005',
'20000000-0000-4000-8000-000000000002',
'Other user', 'private transcript', 'dictation', 'completed', 500, 500,
'1.0.0', now(), now()
);
SET LOCAL ROLE authenticated;
SELECT set_config(
'request.jwt.claims',
'{"sub":"20000000-0000-4000-8000-000000000001","role":"authenticated"}',
true
);
DO $$
DECLARE
stats jsonb := public.mobile_dashboard_stats();
BEGIN
PERFORM pg_temp.assert_true((stats->>'total_sessions')::integer = 3, 'completed own sessions counted');
PERFORM pg_temp.assert_true((stats->>'total_recording_seconds')::numeric = 210, 'duration is exact');
PERFORM pg_temp.assert_true((stats->>'total_word_count')::integer = 35, 'word count is exact');
PERFORM pg_temp.assert_true((stats->>'today_sessions')::integer = 1, 'UTC today count is exact');
PERFORM pg_temp.assert_true((stats->>'streak_days')::integer = 2, 'consecutive streak stops at gap');
PERFORM pg_temp.assert_true(jsonb_array_length(stats->'recent_history') = 3, 'recent history excludes errors and other users');
END;
$$;
RESET ROLE;
ROLLBACK;