feat(catalog): persist idempotent bulk operations and retryable deliveries
CI / check (push) Successful in 3m7s
CI / deploy (push) Successful in 1m37s
CI / publish-container (push) Successful in 44s

This commit is contained in:
Simo committed 2026-09-13 18:05:03 +02:00
1 parent 76e46d295c
commit 13665e0c3c
53 files changed
+1316 -76

No files matched your search

@@ -82,6 +82,7 @@ export function BulkOfferEditor({
const [preview, setPreview] = useState<{
input: BulkInput;
data: Preview;
requestKey: string;
} | null>(null);
const [busy, setBusy] = useState(false);
const busyRef = useRef(false);
@@ -149,7 +150,7 @@ export function BulkOfferEditor({
setError(result.error);
return;
}
setPreview({ input, data: result.data });
setPreview({ input, data: result.data, requestKey: crypto.randomUUID() });
} catch {
setError(t("requestFailed"));
} finally {
@@ -172,12 +173,14 @@ export function BulkOfferEditor({
const result = await applyBulkOffers(
preview.input,
preview.data.fingerprint,
preview.requestKey,
);
if (!result.ok) {
setError(result.error);
setPreview(null);
return;
}
const undoKey = crypto.randomUUID();
toast.success(t("success", { count: result.data.changedCount }), {
duration: 15000,
description: t("undoHint"),
@@ -188,7 +191,10 @@ export function BulkOfferEditor({
if (busyRef.current || (beforeEdit && !beforeEdit())) return;
busyRef.current = true;
try {
const restored = await undoBulkOffers(result.data.historyIds);
const restored = await undoBulkOffers(
result.data.historyIds,
undoKey,
);
if (!restored.ok) {
toast.error(restored.error);
return;
@@ -210,7 +216,6 @@ export function BulkOfferEditor({
await onApplied();
} catch {
setError(t("requestFailed"));
setPreview(null);
} finally {
busyRef.current = false;
setBusy(false);