fix(catalog): route item-table writes to the catalog they belong to
Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 32s
CI / tests-integration (push) Successful in 1m43s
CI / tests-unit (push) Successful in 1m48s
CI / tests-ui (push) Successful in 2m37s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m16s
Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 32s
CI / tests-integration (push) Successful in 1m43s
CI / tests-unit (push) Successful in 1m48s
CI / tests-ui (push) Successful in 2m37s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m16s
The items table is shared between both catalogs, but its four mutating actions were normal-only: moving, reordering, creating and updating a Builder Club offer wrote to catalog_items, so a BC edit either landed in the wrong catalog or hit an unknown column. Pass the catalog from the table through the actions and let the server resolve it. BC rows have no price, points or currency column, so the BC commands strip those fields instead of rejecting them. Moving and reordering now share one command that locks the category and writes the table for the same catalog, and BC writes revalidate the BC route.
This commit is contained in:
1 parent
e0efbef30d
commit
cede541813
3 files changed
+155
-50
No files matched your search
@@ -11,7 +11,9 @@ import {
|
||||
} from "@/features/catalog/server/item-deletes";
|
||||
import {
|
||||
createOfferCommand,
|
||||
moveBcOffersCommand,
|
||||
moveOffersCommand,
|
||||
reorderBcOffersCommand,
|
||||
reorderOffersCommand,
|
||||
updateOfferCommand,
|
||||
} from "@/features/catalog/server/offer-commands";
|
||||
@@ -66,24 +68,40 @@ export async function insertCatalogItemRow(data: {
|
||||
);
|
||||
}
|
||||
|
||||
export async function createCatalogItem(data: {
|
||||
pageId: number;
|
||||
itemIds: string;
|
||||
catalogName: string;
|
||||
costCredits: number;
|
||||
costPoints: number;
|
||||
pointsType: number;
|
||||
amount: number;
|
||||
orderNumber: number;
|
||||
offerId: number;
|
||||
limitedSells: number;
|
||||
limitedStack: number;
|
||||
extradata: string;
|
||||
songId: number;
|
||||
haveOffer: "0" | "1";
|
||||
clubOnly: "0" | "1";
|
||||
}) {
|
||||
export async function createCatalogItem(
|
||||
data: {
|
||||
pageId: number;
|
||||
itemIds: string;
|
||||
catalogName: string;
|
||||
costCredits: number;
|
||||
costPoints: number;
|
||||
pointsType: number;
|
||||
amount: number;
|
||||
orderNumber: number;
|
||||
offerId: number;
|
||||
limitedSells: number;
|
||||
limitedStack: number;
|
||||
extradata: string;
|
||||
songId: number;
|
||||
haveOffer: "0" | "1";
|
||||
clubOnly: "0" | "1";
|
||||
},
|
||||
// The table is shared between both catalogs, and a BC offer has no price or
|
||||
// currency columns at all. The catalog decides which command runs rather than
|
||||
// letting the table send normal-only fields at a BC row.
|
||||
catalog: "normal" | "bc" = "normal",
|
||||
) {
|
||||
const staff = await requirePermission(PERMS.CATALOG_EDIT);
|
||||
if (catalog === "bc") {
|
||||
const { createBcItem } = await import("@/actions/catalog-bc");
|
||||
return createBcItem({
|
||||
pageId: data.pageId,
|
||||
itemIds: data.itemIds,
|
||||
catalogName: data.catalogName,
|
||||
orderNumber: data.orderNumber,
|
||||
extradata: data.extradata,
|
||||
});
|
||||
}
|
||||
return await withCatalogExport(async () => {
|
||||
let catalogName = data.catalogName.trim();
|
||||
if (!catalogName) {
|
||||
@@ -297,32 +315,42 @@ export async function restoreDeletedCatalogItems({
|
||||
export async function moveCatalogItems({
|
||||
ids,
|
||||
targetPageId,
|
||||
catalog = "normal",
|
||||
}: {
|
||||
ids: number[];
|
||||
targetPageId: number;
|
||||
catalog?: "normal" | "bc";
|
||||
}) {
|
||||
await requirePermission(PERMS.CATALOG_EDIT);
|
||||
return await withCatalogExport(async () => {
|
||||
if (ids.length === 0) {
|
||||
return { ok: true as const, data: {} };
|
||||
}
|
||||
await moveOffersCommand(ids, targetPageId);
|
||||
// Moving BC offers has to lock a BC category and write the BC table; the
|
||||
// normal command would move a row in the wrong catalog.
|
||||
if (catalog === "bc") await moveBcOffersCommand(ids, targetPageId);
|
||||
else await moveOffersCommand(ids, targetPageId);
|
||||
await sendCatalogUpdate();
|
||||
revalidatePath("/admin/catalog");
|
||||
if (catalog === "bc") revalidatePath("/admin/catalog/builder-club");
|
||||
return { ok: true as const, data: {} };
|
||||
});
|
||||
}
|
||||
|
||||
export async function reorderCatalogItems({
|
||||
orders,
|
||||
catalog = "normal",
|
||||
}: {
|
||||
orders: Array<{ id: number; orderNumber: number }>;
|
||||
catalog?: "normal" | "bc";
|
||||
}) {
|
||||
await requirePermission(PERMS.CATALOG_EDIT);
|
||||
return await withCatalogExport(async () => {
|
||||
await reorderOffersCommand(orders);
|
||||
if (catalog === "bc") await reorderBcOffersCommand(orders);
|
||||
else await reorderOffersCommand(orders);
|
||||
await sendCatalogUpdate();
|
||||
revalidatePath("/admin/catalog");
|
||||
if (catalog === "bc") revalidatePath("/admin/catalog/builder-club");
|
||||
return { ok: true as const, data: {} };
|
||||
});
|
||||
}
|
||||
@@ -331,12 +359,21 @@ export async function updateCatalogItem({
|
||||
id,
|
||||
catalogFields,
|
||||
baseItem,
|
||||
catalog = "normal",
|
||||
}: {
|
||||
id: number;
|
||||
catalogFields: Record<string, unknown>;
|
||||
baseItem?: { id: number; fields: Record<string, unknown> };
|
||||
catalog?: "normal" | "bc";
|
||||
}) {
|
||||
const staff = await requirePermission(PERMS.CATALOG_EDIT);
|
||||
// BC rows have no price, points or currency column. The table is shared, so
|
||||
// the catalog is resolved here rather than trusting the caller to strip
|
||||
// fields the BC command would reject anyway.
|
||||
if (catalog === "bc") {
|
||||
const { updateBcItem } = await import("@/actions/catalog-bc");
|
||||
return updateBcItem({ id, ...catalogFields });
|
||||
}
|
||||
return await withCatalogExport(async () => {
|
||||
try {
|
||||
await updateOfferCommand({ id, catalogFields, baseItem }, staff.id);
|
||||
|
||||
Reference in new issue
Block a user