From b7dfe00200d33d44de6f472810004924ce5b8005 Mon Sep 17 00:00:00 2001 From: metatroncubeswdev Date: Fri, 30 Oct 2026 21:33:44 -0400 Subject: [PATCH] Clear cached subscriptions on uninstall so a quick reinstall asks for a plan Co-Authored-By: Claude Opus 5.5 --- app/lib/partner.server.ts | 5 +++++ app/routes/webhooks.app.uninstalled.tsx | 2 ++ 2 files changed, 7 insertions(+) diff --git a/app/lib/partner.server.ts b/app/lib/partner.server.ts index cd54e32..2bf22f8 100644 --- a/app/lib/partner.server.ts +++ b/app/lib/partner.server.ts @@ -23,6 +23,11 @@ export interface ActiveSubscription { const CACHE_MS = 5 * 60 * 1000; const cache = new Map(); +/** Called on app/uninstalled: the subscription is cancelled then, so a quick reinstall must not see a cached plan. */ +export function forgetSubscriptions() { + cache.clear(); +} + export function partnerApiConfigured() { return !!(process.env.SHOPIFY_PARTNER_ORG_ID && process.env.SHOPIFY_PARTNER_API_ACCESS_TOKEN && process.env.SHOPIFY_APP_GID); } diff --git a/app/routes/webhooks.app.uninstalled.tsx b/app/routes/webhooks.app.uninstalled.tsx index ca91907..ecabcb3 100644 --- a/app/routes/webhooks.app.uninstalled.tsx +++ b/app/routes/webhooks.app.uninstalled.tsx @@ -1,6 +1,7 @@ import type { ActionFunctionArgs } from "react-router"; import { authenticate } from "../shopify.server"; import db from "../db.server"; +import { forgetSubscriptions } from "../lib/partner.server"; // The access token is already revoked here, so the app can't call the Admin API. Shopify removes the app's // functions with the app, so the automatic discount stops applying, and it deletes app-owned ($app and @@ -10,6 +11,7 @@ export const action = async ({ request }: ActionFunctionArgs) => { const { shop, session, topic } = await authenticate.webhook(request); console.log(`Received ${topic} webhook for ${shop}`); + forgetSubscriptions(); await db.shop.updateMany({ where: { domain: shop }, data: { uninstalledAt: new Date(), discountNodeId: null, nextSyncAt: null } }); if (session) await db.session.deleteMany({ where: { shop } }); return new Response();