b07a4a4bca
seed_trial_capability_grants() still hardcoded ai/bank_sync/skatteverket/ email_send while PAID_CAPABILITIES grew to seven keys. Payers got all seven via the Stripe webhook; every company created since 2026-07-12 was trialing without stripe_payments (and later woocommerce_sync/shopify_sync). Redefine the trigger with the full set, backfill existing trial grants by mirroring bank_sync, and pin the pg test to PAID_CAPABILITIES so the lists cannot drift again. Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
61 lines
2.3 KiB
PL/PgSQL
61 lines
2.3 KiB
PL/PgSQL
-- Trial seeding must grant every PAID capability, not the 2026-06-29 four.
|
|
--
|
|
-- lib/entitlements/keys.ts PAID_CAPABILITIES grew to seven keys
|
|
-- (stripe_payments 2026-07-12, woocommerce_sync 2026-08-06, shopify_sync
|
|
-- 2026-08-08). The Stripe webhook writes grants from that constant, so
|
|
-- payers have all seven; the trial trigger seed_trial_capability_grants()
|
|
-- (20260629120000) still hardcodes ('ai','bank_sync','skatteverket',
|
|
-- 'email_send'), and each key's backfill only mirrored the grants that
|
|
-- existed on its day. Every company created since is trialing without the
|
|
-- newer keys: on 2026-08-18, 226 of 230 active trialers lacked
|
|
-- stripe_payments, 146 woocommerce_sync, 131 shopify_sync.
|
|
--
|
|
-- 1. Redefine the trigger function with the full PAID set. Keep this VALUES
|
|
-- list in step with PAID_CAPABILITIES whenever a key is added (and add a
|
|
-- backfill like part 2 for the companies already seeded).
|
|
-- 2. Backfill: mirror every existing trial bank_sync grant (same company,
|
|
-- same expiry) for the three missing keys. Idempotent via the unique
|
|
-- index; expired trials are mirrored too so state stays aligned, exactly
|
|
-- as the earlier backfills did.
|
|
|
|
CREATE OR REPLACE FUNCTION public.seed_trial_capability_grants()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path = public
|
|
AS $$
|
|
BEGIN
|
|
INSERT INTO public.capability_grants (company_id, capability_key, source, expires_at)
|
|
SELECT NEW.id, k.key, 'trial', NEW.created_at + interval '30 days'
|
|
FROM (VALUES
|
|
('ai'),
|
|
('bank_sync'),
|
|
('skatteverket'),
|
|
('email_send'),
|
|
('stripe_payments'),
|
|
('woocommerce_sync'),
|
|
('shopify_sync')
|
|
) AS k(key)
|
|
ON CONFLICT (company_id, team_id, capability_key, source) DO NOTHING;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
|
|
INSERT INTO public.capability_grants
|
|
(company_id, team_id, capability_key, source, granted_at, expires_at, metadata)
|
|
SELECT
|
|
g.company_id,
|
|
g.team_id,
|
|
k.key,
|
|
g.source,
|
|
g.granted_at,
|
|
g.expires_at,
|
|
jsonb_build_object(
|
|
'backfilled_from', 'bank_sync',
|
|
'backfill_migration', '20260818170000'
|
|
)
|
|
FROM public.capability_grants g
|
|
CROSS JOIN (VALUES ('stripe_payments'), ('woocommerce_sync'), ('shopify_sync')) AS k(key)
|
|
WHERE g.capability_key = 'bank_sync' AND g.source = 'trial'
|
|
ON CONFLICT (company_id, team_id, capability_key, source) DO NOTHING;
|