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
@@ -10,6 +10,12 @@
|
||||
* assets live in the pet asset pipeline (`public/nitro-assets/bundled/pet`),
|
||||
* not the furniture bundle dirs.
|
||||
* - **effect / bot / sticky** — system items with no furniture visuals at all.
|
||||
* - **poster** — poster furniture (`poster*` classnames, wall posters, novelty
|
||||
* poster furni). Renders through the poster imager, so no `.nitro` / `_icon.png`
|
||||
* assets are expected.
|
||||
* - **currency** — credit/pixel furniture (`CF_*`, `DF_*`). Renders through the
|
||||
* currency imager (credits coin, badge-format exchange stickers), so no
|
||||
* `.nitro` / `_icon.png` assets are expected.
|
||||
* - **furni** — everything else; must ship a `.nitro` and `_icon.png`.
|
||||
*/
|
||||
|
||||
@@ -19,6 +25,8 @@ export type CatalogItemKind =
|
||||
| "effect"
|
||||
| "bot"
|
||||
| "sticky"
|
||||
| "poster"
|
||||
| "currency"
|
||||
| "furni";
|
||||
|
||||
export interface CatalogItemLike {
|
||||
@@ -42,6 +50,24 @@ export function isPetInteraction(interactionType?: string | null): boolean {
|
||||
return /^pet\d+$/i.test((interactionType ?? "").trim());
|
||||
}
|
||||
|
||||
/** Poster furniture classnames that have no `.nitro` asset expectations. */
|
||||
export function isPosterClassname(itemName: string): boolean {
|
||||
const name = itemName.trim();
|
||||
if (/^poster\d+$/i.test(name)) return true;
|
||||
const POSTER_SPECIAL = new Set([
|
||||
"funtastic_four_poster",
|
||||
"duckfountain",
|
||||
"duckfountain2",
|
||||
"swimming",
|
||||
]);
|
||||
return POSTER_SPECIAL.has(name.toLowerCase());
|
||||
}
|
||||
|
||||
/** Credit/pixel furniture (`CF_*`, `DF_*`) ships no `.nitro` assets. */
|
||||
export function isCurrencyClassname(itemName: string): boolean {
|
||||
return /^(?:cf|df)_/i.test(itemName.trim());
|
||||
}
|
||||
|
||||
/** Classify an `items_base` row into a catalog item kind. */
|
||||
export function classifyCatalogItem(item: CatalogItemLike): CatalogItemKind {
|
||||
const name = item.item_name.trim();
|
||||
@@ -52,6 +78,8 @@ export function classifyCatalogItem(item: CatalogItemLike): CatalogItemKind {
|
||||
if (/^avatar_effect/i.test(name)) return "effect";
|
||||
if (/^(bot_|rentable_bot_)/i.test(name)) return "bot";
|
||||
if (/^post[._]?it/i.test(name)) return "sticky";
|
||||
if (isPosterClassname(name)) return "poster";
|
||||
if (isCurrencyClassname(name)) return "currency";
|
||||
return "furni";
|
||||
}
|
||||
|
||||
@@ -62,6 +90,8 @@ export const NO_ASSET_KINDS: ReadonlySet<CatalogItemKind> = new Set([
|
||||
"effect",
|
||||
"bot",
|
||||
"sticky",
|
||||
"poster",
|
||||
"currency",
|
||||
]);
|
||||
|
||||
/** Kinds that are not purchasable furniture and should not get catalog entries. */
|
||||
|
||||
Reference in new issue
Block a user