feat(catalog): prevent and repair Arcturus emulator data errors
CI / check (push) Failing after 26s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped

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:
openhands committed 2026-09-10 11:29:28 +02:00
1 parent ad65d80d41
commit 3e69b72513
26 files changed
+17651 -3844

No files matched your search

@@ -40,6 +40,7 @@ interface CloneSource {
nitroBaseUrl: string;
iconBaseUrl: string;
hotel: string;
enabled?: boolean;
}
interface FurniItem {
@@ -81,6 +82,7 @@ function SourceForm({ initial, onSave, onCancel, saving }: SourceFormProps) {
const [nitroBaseUrl, setNitroBaseUrl] = useState(initial?.nitroBaseUrl ?? "");
const [iconBaseUrl, setIconBaseUrl] = useState(initial?.iconBaseUrl ?? "");
const [hotel, setHotel] = useState(initial?.hotel ?? "");
const [enabled, setEnabled] = useState(initial?.enabled ?? true);
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
@@ -91,6 +93,7 @@ function SourceForm({ initial, onSave, onCancel, saving }: SourceFormProps) {
nitroBaseUrl,
iconBaseUrl,
hotel,
enabled,
});
}
@@ -140,6 +143,15 @@ function SourceForm({ initial, onSave, onCancel, saving }: SourceFormProps) {
))}
</SelectContent>
</Select>
<label className="flex items-center gap-2 text-sm">
<input
type="checkbox"
checked={enabled}
onChange={(e) => setEnabled(e.target.checked)}
className="h-4 w-4 rounded border-input"
/>
Enabled (retired sources are excluded from counts and imports)
</label>
</div>
<div className="flex gap-2">
<Button type="submit" size="sm" disabled={saving}>