Rust discount function (one automatic discount evaluating all offers in priority order, parity with the Odoo engine), React Router admin with Polaris, theme app extension and app proxy pages, webhooks incl. GDPR, managed-pricing limits, and a Docker Compose stack (Postgres + Caddy HTTPS) for a single VPS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 lines
1.6 KiB
TypeScript
31 lines
1.6 KiB
TypeScript
import type { ActionFunctionArgs } from "react-router";
|
|
import { authenticate, unauthenticated } from "../shopify.server";
|
|
import db from "../db.server";
|
|
import { planCodeFromSubscription, planOf } from "../lib/plans";
|
|
import { enforcePlanOnPublished } from "../lib/offers.server";
|
|
import { publishShop } from "../lib/publish.server";
|
|
|
|
// Managed pricing plan changes (§18.2): store the plan, unpublish offers above the new limit, republish.
|
|
export const action = async ({ request }: ActionFunctionArgs) => {
|
|
const { shop, payload } = await authenticate.webhook(request);
|
|
const sub = (payload as { app_subscription?: { name?: string; status?: string } }).app_subscription;
|
|
const active = sub?.status?.toUpperCase() === "ACTIVE";
|
|
const planCode = active ? planCodeFromSubscription(sub?.name) : "free";
|
|
const row = await db.shop.findUnique({ where: { domain: shop } });
|
|
if (!row) return new Response();
|
|
await db.shop.update({ where: { id: row.id }, data: { planCode } });
|
|
const plan = planOf(planCode);
|
|
const unpublished = await enforcePlanOnPublished(row.id, plan.runningOffers, plan.types);
|
|
if (unpublished) {
|
|
await db.auditLog.create({ data: { shopId: row.id, field: "plan", newValue: `${plan.name}: ${unpublished} offer(s) unpublished (over the plan limit)` } });
|
|
}
|
|
try {
|
|
const { admin } = await unauthenticated.admin(shop);
|
|
await publishShop(admin, shop);
|
|
} catch (e) {
|
|
console.error("publish after plan change failed", e);
|
|
await db.shop.update({ where: { id: row.id }, data: { nextSyncAt: new Date() } });
|
|
}
|
|
return new Response();
|
|
};
|