feat: comprehensive CMS improvements
- Fix DOMPurify SSR crash (use isomorphic-dompurify) - Fix SanitizedHtml to sanitize by default - Add auth guards to studio/catalog maintenance pages - Add update/edit to vouchers CRUD - Add update/edit to rare-values CRUD - Add approve workflow to applications page - Add edit form to guilds detail page - Add SEO metadata to all public pages (21 pages) - Fix mobile nav accessibility (focus trap, aria attributes) - Fix missing labels and table accessibility - Add dynamic imports for heavy client components (6 components) - Fix silent error swallowing (40+ locations) - Add content scheduling for articles (publishAt, status) - Wire up 12 missing webhook notification triggers - Add global search to admin panel - Add bulk actions to admin users table - Fix JSON formatting and a11y issues
This commit is contained in:
1 parent
b810b16672
commit
30c95b1a5c
78 files changed
+2252
-134
No files matched your search
@@ -3,6 +3,7 @@ import path from "node:path";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
import { db, ItemsBase } from "@/lib/db";
|
||||
import { autoDetectInteraction } from "@/lib/furni/auto-interaction";
|
||||
import { logServerError } from "@/lib/server-log";
|
||||
import { getFurniAssetWriteTargets } from "@/lib/services/furni-asset-dirs";
|
||||
import { appendFurniEntry, buildFurniEntry } from "@/lib/services/furni-data";
|
||||
import {
|
||||
@@ -96,7 +97,9 @@ async function allocateItemsBaseId<T>(
|
||||
itemsBaseIdSeedChain = new Promise<void>((r) => {
|
||||
settle = r;
|
||||
});
|
||||
await prev.catch(() => {});
|
||||
await prev.catch((error) =>
|
||||
logServerError("upload.items_base_id_chain_failed", error),
|
||||
);
|
||||
try {
|
||||
if (
|
||||
itemsBaseNextId === null ||
|
||||
@@ -358,10 +361,25 @@ export async function uploadSingleFurni(params: {
|
||||
return nextId;
|
||||
});
|
||||
} catch (err) {
|
||||
await fs.unlink(nitroPath).catch(() => {});
|
||||
if (iconPath) await fs.unlink(iconPath).catch(() => {});
|
||||
await fs
|
||||
.unlink(nitroPath)
|
||||
.catch((error) =>
|
||||
logServerError("upload.cleanup_nitro_failed", error, { classname }),
|
||||
);
|
||||
if (iconPath)
|
||||
await fs
|
||||
.unlink(iconPath)
|
||||
.catch((error) =>
|
||||
logServerError("upload.cleanup_icon_failed", error, { classname }),
|
||||
);
|
||||
await Promise.all(
|
||||
mirroredPaths.map((file) => fs.unlink(file).catch(() => {})),
|
||||
mirroredPaths.map((file) =>
|
||||
fs
|
||||
.unlink(file)
|
||||
.catch((error) =>
|
||||
logServerError("upload.cleanup_mirror_failed", error, { file }),
|
||||
),
|
||||
),
|
||||
);
|
||||
return {
|
||||
ok: false,
|
||||
|
||||
Reference in new issue
Block a user