feat(catalog): prevent and repair Arcturus emulator data errors
Block invalid catalog_items writes at the API level (points currency allowlist, non-negative prices, positive amount, limited stack >= sold count, unique sibling order numbers) and auto-assign unique order numbers on bulk create. Add a catalog-maintenance scan + transactional repair that fixes pre-existing rows: resets unsupported points_type, clamps negative costs, sets amount to 1, raises limited_stack, renumbers duplicate orders and deletes offers with missing page/item references. Surface the issue count and a fix button in the admin maintenance panel. Also: add enabled/retired flag to clone sources, classify poster and currency furniture in item-kind, and remove the obsolete update-Nitrov3.sh.
This commit is contained in:
1 parent
ad65d80d41
commit
3e69b72513
26 files changed
+17651
-3844
No files matched your search
@@ -144,6 +144,12 @@ export async function bulkCreateCatalogItems({
|
||||
let created = 0;
|
||||
let failed = 0;
|
||||
|
||||
// Find the next order number on the target page to avoid collisions.
|
||||
const [maxOrder] = (await db.execute(sql`
|
||||
SELECT COALESCE(MAX(order_number), 0) AS maxOrder FROM catalog_items WHERE page_id = ${String(pageId)}
|
||||
`)) as unknown as [{ maxOrder: number }, unknown];
|
||||
let nextOrder = Number(maxOrder?.maxOrder ?? 0) + 1;
|
||||
|
||||
for (const row of rows) {
|
||||
const base = baseMap.get(row.baseId);
|
||||
if (!base) {
|
||||
@@ -161,7 +167,7 @@ export async function bulkCreateCatalogItems({
|
||||
amount: 1,
|
||||
limitedSells: 0,
|
||||
limitedStack: 0,
|
||||
orderNumber: 1,
|
||||
orderNumber: nextOrder++,
|
||||
offerId: -1,
|
||||
songId: 0,
|
||||
haveOffer: "1",
|
||||
|
||||
@@ -11,6 +11,7 @@ import { withCatalogExport } from "@/lib/services/catalog-git-queue";
|
||||
import type {
|
||||
AlignResult,
|
||||
DedupResult,
|
||||
FixEmulatorResult,
|
||||
FixOfferResult,
|
||||
FixSpriteResult,
|
||||
FurniHealth,
|
||||
@@ -60,6 +61,19 @@ export async function fixCatalogOffersAction(): Promise<
|
||||
}
|
||||
}
|
||||
|
||||
export async function fixEmulatorIssuesAction(): Promise<
|
||||
ActionResult<FixEmulatorResult>
|
||||
> {
|
||||
try {
|
||||
await guard();
|
||||
return await withCatalogExport(async () => {
|
||||
return actionOk(await maintenance.fixEmulatorIssues());
|
||||
});
|
||||
} catch (e) {
|
||||
return handleActionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function reconcileIdsAction(): Promise<
|
||||
ActionResult<ReconcileResult>
|
||||
> {
|
||||
|
||||
Reference in new issue
Block a user